是否存在执行 bash 历史记录中的一系列命令的快捷方式?

MrD*_*Duk 20 command-line bash command-history

假设我的 中有以下简单示例history

...
76 cd ~
77 ./generator.sh out.file
78 cp out.file ~/out/
79 ./out/cleaner.sh .
80 ls -alnh /out
...
Run Code Online (Sandbox Code Playgroud)

如果我想在一个命令中执行命令777879,是否存在快捷方式?我试过!77 !78 !79,它只会将它们全部放在一行上执行。

Wil*_*ard 28

编辑:您可以使用fix 命令工具fc以符合 POSIX 的方式执行此操作:

fc 77 79
Run Code Online (Sandbox Code Playgroud)

这将vi使用缓冲区中的命令 77 到 79打开您的编辑器(可能)。当您保存并退出 ( :x) 时,将运行命令。


如果你不想编辑它们并且你非常确定你知道你正在调用哪些命令,你可以使用:

fc -e true 77 79
Run Code Online (Sandbox Code Playgroud)

true用作“编辑器”来编辑命令,因此它只是退出而不进行任何更改并且命令按原样运行。


原始答案:

您可以使用:

history -p \!{77..79} | bash
Run Code Online (Sandbox Code Playgroud)

这假设您没有使用任何别名或函数或任何仅存在于当前执行环境中的变量,当然这些在正在启动的新 shell 中将不可用。


更好的解决方案(感谢 Michael Hoffman 在评论中提醒我)是:

eval "$(history -p \!{77..79})"
Run Code Online (Sandbox Code Playgroud)

eval真正合适的极少数情况之一!


另见:

  • `eval "$(history -p \!{77..79})"` 应该可以工作。 (3认同)
  • 如果任何命令*改变*当前的执行环境,这将无法正常工作,例如,通过更改变量或执行`cd`,但这是一个边缘情况。 (2认同)

G-M*_*ca' 14

简单的答案:而不是!77 !78 !79

  • 键入!77; !78; !79以执行您似乎正在尝试执行的操作 - 无条件地执行命令 77,然后执行命令 78,然后执行命令 79,或者
  • 键入!77 && !78 && !79 执行命令77并检查是否成功。然后,如果命令 77 成功,则执行命令 78。然后,如果命令 78 成功,则执行命令 79。

稍微聪明一点的答案(如果您在终端类型的窗口中):

  • 弄清楚您键入的下一个命令将是什么命令编号。
    • 可以将其包含在您的提示中;我相信这是通过包含\!在您的PS1.
    • 或者查看您的历史列表。如果最后一个条目是82 history,那么您的下一个命令是 83。
  • 减去 83?77=6。
  • 键入!-6。这将重新执行命令 77。
  • 选择!-6,复制并粘贴它。由于您重新执行命令 77 ( ./generator.sh) 是命令 83,因此您现在处于命令 84,因此!-6将重新执行命令 78。
  • !-6根据需要重复粘贴。