How to execute consecutive commands from history?

56,222

Solution 1

If it refers to commands run just recently, a more efficient way is to reference them with negative numbers:

!-4; !-3; !-2; !-1

Also, once you do it, your last history entry will contain the whole chain of commands, so you can repeat it with !!.


Edit: If you haven't already, get familiar with the great builtin function fc, mentioned by Gilles. (Use help fc.) It turns out that you can also use negative numbers with it, so you could do the same as above using

eval "`fc -ln -4 -1`"

This has one caveat, though: after this, the eval line is stored in the history as the last command. So if you run this again, you'll fall into a loop!

A safer way of doing this is to use the default fc operation mode: forwarding the selected range of commands to an editor and running them once you exit from it. Try:

 fc -4 -1

You can even reverse the order of the range of commands: fc -1 -4

Solution 2

To view a range of commands in the history use the built-in fc command:

fc -ln 432 435

To execute them again:

eval "$(fc -ln 432 435)"

Solution 3

There is a nice and alternate way to run a number of commands in sequence from the Bash history:
instead of using history substitute (!432 or !-4), you can search through the history with Ctrl+r, and once you've found the first command you want to run, hit Ctrl+o (operate-and-get-next) instead of the return key
This will launch the command and propose the next one from the history. You can hit Ctrl+o as many time as you wish, and end the sequence either with return for a last one, or Ctrl+c to stop without launching it.

Solution 4

To execute the commands immediately rather than edit them, here is a syntactically slimmer version of Giles answer using eval:

fc -e: 432 435

The colon argument to -e is the bash noop, which has the effect of skipping the "open in an editor" step that fc wants. Also, now the (recent) history will contain the actual commands from history, rather than the eval statement.

Share:
56,222

Related videos on Youtube

Eric Wilson
Author by

Eric Wilson

Updated on September 18, 2022

Comments

  • Eric Wilson
    Eric Wilson over 1 year

    Suppose I want to execute a sequence of four commands that I have executed before. If the first one is 432 in the command-history, then I could do:

    $ !432; !433; !434; !435
    

    I'm curious, is there a more efficient way to accomplish this?

    • Wildcard
      Wildcard about 8 years
      Not posting this as an answer because it doesn't execute the commands, but you could type history -p \!43{2..5} to print commands 432 through 435 to the terminal, suitable for subsequent copy/paste.
  • rozcietrzewiacz
    rozcietrzewiacz over 12 years
    I just read what I'd written... LOL. Actually, I'm not sure about reinvoke (re-invoke maybe?), but thanks for telling :) I always appreciate corrections.
  • alexanderkustov
    alexanderkustov over 12 years
    Scrabblefinder.com says reinvoke is a valid Scrabble word. Can't get any more definitive than that. :)
  • Eric Wilson
    Eric Wilson over 12 years
    Very nice. I'm curious though, why man fc doesn't give me anything. What does fc stand for? What other options are there?
  • Peter.O
    Peter.O over 12 years
    With a good answer like this one (+1), it doesn't matter how you spell it; especially as neither spelling form shows up in 3 major English dictionaries: Oxford, Camgridge, Merriam-Webster (I'd go for the hyphen)
  • Peter.O
    Peter.O over 12 years
    @Eric Wilson ... type help fc... and also help help .... help: help [-dms] [pattern ...] Display information about builtin commands.
  • rozcietrzewiacz
    rozcietrzewiacz almost 12 years
    I just came back here, searching for your answer. This really is a great builtin! Especially when you is its default functionality - invoking an editor to modify a range of commands to be replayed. Thanks, Gilles.
  • Bernhard
    Bernhard over 10 years
    Without -l flag, it will execute without need for the evil eval.
  • Johannes Jarolim
    Johannes Jarolim almost 9 years
    @Bernhard There's nothing evil about eval. This isn't javascript. Understand the tool and don't arbitrarily toss shade because it's de rigueur.
  • Slothworks
    Slothworks over 8 years
    @EricWilson A google search lead me to the "Unix in a Nutshell" book which says fc stands for "find command" or "fix command".
  • Ciro Santilli Путлер Капут 六四事
    Ciro Santilli Путлер Капут 六四事 about 6 years
    Hmm, after I hit Ctrl-o it just outputs a literal ^o and breaks my (reverse-i-search). Maybe there is some other setting involved.
  • Jeff Schaller
    Jeff Schaller about 4 years
    I'm not sure that redirection, editing, executing a script, and then potentially removing the temporary file is a "more efficient way to accomplish this".
  • Jeff Schaller
    Jeff Schaller about 4 years
    Also, what's the intention behind bash c?
  • mCeviker
    mCeviker about 4 years
    this is the most practical answer
  • Gali Stinsonz
    Gali Stinsonz almost 3 years
    thank you very much! couldn't recall the combination and had hard time finding it, although the combination is quite simple