Does a shortcut for executing a series of commands in bash history exist?

Suppose I have the following trivial example in my history:

...
76 cd ~
77 ./generator.sh out.file
78 cp out.file ~/out/
79 ./out/cleaner.sh .
80 ls -alnh /out
...

If I wanted to execute commands 77, 78, and 79 in one command, does there exist a shortcut for this? I’ve tried !77 !78 !79, which will simply place them all on a single line to execute.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

EDIT: You can do this in POSIX-compliant fashion with the fix command tool fc:

fc 77 79

This will open your editor (probably vi) with commands 77 through 79 in the buffer. When you save and exit (:x), the commands will be run.


If you don’t want to edit them and you’re VERY SURE you know which commands you’re calling, you can use:

fc -e true 77 79

This uses true as an “editor” to edit the commands with, so it just exits without making any changes and the commands are run as-is.


ORIGINAL ANSWER:

You can use:

history -p !{77..79} | bash

This assumes that you’re not using any aliases or functions or any variables that are only present in the current execution environment, as of course those won’t be available in the new shell being started.


A better solution (thanks to Michael Hoffman for reminding me in the comments) is:

eval "$(history -p !{77..79})"

One of the very, very few cases where eval is actually appropriate!


Also see:

Method 2

Simple answer: instead of !77 !78 !79,

  • type !77; !78; !79 to do what you seem to be trying to do —
    execute command 77, and then command 78, and then command 79, unconditionally,
    or
  • type !77 && !78 && !79
    to execute command 77 and check whether it succeeded. 
    And then, if command 77 succeeded, execute command 78. 
    And then, if command 78 succeeded, execute command 79.

Slightly cleverer answer (if you are in a terminal-type window):

  • Figure out what command number the next command you type will be.
    • It is possible to include this in your prompt;
      I believe it’s by including ! in your PS1.
    • Or look at your history listing. 
      If the last entry is 82 history, then your next command is 83.
  • Subtract 83−77=6.
  • Type !-6
    This will re-execute command 77.
  • Select the !-6, copy it, and paste it. 
    Since your re-execution of command 77 (./generator.sh) was command 83,
    you are now on command 84, so !-6will re-execute command 78.
  • Repeat pasting !-6 as desired.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x