Short of writing a loop, is there a way to repeat the last command N times.

For example, I can repeat the last command once by using a double bang (!!), but how do I repeat it say 30 times?

share|improve this question

With zsh, and provided the last command line was only one command or pipeline or and-or list (that is for instance echo x, echo x | tr x y, echo x && echo y, even compound commands like { x; y; } or for/while loops but not echo x; echo y):

repeat 30 !!

To repeat the previous command line even if it contained several commands, use:

repeat 30 do !!; done

Or:

repeat 30 {!!}

With bash and for simple-commands only (among the examples above, only the echo x case), you could define a helper function like:

repeat() {
  local n="$1"
  shift
  while ((n-- > 0)); do
    "$@"
  done
}

(and use repeat 30 !! like above). A side effect is that because the code will be running in a function, it will see different "$@", "$#" and things like typeset will work differently, so you can't do things like:

eval 'echo "$1"'
repeat 30 !!

Another approach to emulate zsh's repeat 30 {!!} would be to declare an alias like:

alias repeat='for i in $(seq'

(assuming an unmodified $IFS)

And then use:

repeat 30); { !!; }
share|improve this answer

The shortest I can come up with is:

date # or whatever command
for i in {1..30}; do !!; done
share|improve this answer
2  
That has a loop. – Tyler Durden Jun 21 at 12:54
4  
You can shorten it to for i in {1..30};{ !!;} – Stéphane Chazelas Jun 21 at 13:05

One approach could be to use the line editor to insert !!; 30 times.

Like with readline (bash's line editor) in vi mode:

!!;Escdd30p

The emacs mode equivalent does work with the zsh line editor but apparently not with bash's readline. However you could use readline kbd macros instead which apparently can be repeated:

Define the kbd macro as !!;:

Ctrl+X(!!;Ctrl+X)

Which you can later invoke 30 times as:

Alt+3Alt+0Ctrl+Xe
share|improve this answer

This is a bit ugly, but:

 eval "`fc -ln -1`;: "{1..10}\;

The leading space is not strictly necessary, but is useful to suppress entering the eval command into history if $HISTCONTROL contains ignorespace (or ignoreboth).

Alternatively:

eval "fc -s $((HISTCMD-2)) "{1..10}\;

And:

eval 'history -s '{1..10}';fc -s -2;'
share|improve this answer
    
@StéphaneChazelas good point, thanks. – ecatmur Jun 21 at 14:38

The seq command is part of standard *nix and therefore not dependent on your shell. Using it and your shell's loop construct you can do things like this:

for i in $(seq 30); do !!; done

or

for i in `seq 30`; do !!; done

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.