fed*_*qui 18 bash command-history readline
在 UNIX 系统中,您可以按顶部和底部箭头来浏览前面的命令。这非常方便。
有时,我会上去找到一个我想再次使用的命令,但有一些变化。如果我进行了这样的更改,那么我就没有办法恢复原来的命令,除非我在history
.
有什么方法可以“撤消”通过键访问的历史记录中对命令的更改?
我目前的解决方法是#
在命令前加上 a 。这样,当前命令作为注释执行,所以什么也没有发生。然后,我可以使用按键再次浏览命令。问题是我使用的命令可能在列表中很远,所以再次上升 200 次有点 。Control + R 也不是解决方案,因为我可能不记得我在找什么。
我输入了以下“50个命令前”:
ls -l /etc/httpd/conf/
Run Code Online (Sandbox Code Playgroud)
现在我走到那条线并将其更改为
ls -l /etc/init.d/
Run Code Online (Sandbox Code Playgroud)
但没有按回车键。现在,我想ls -l /etc/httpd/conf/
再次到达。
$ echo $SHELL
/bin/bash
$ echo $TERM
xterm
Run Code Online (Sandbox Code Playgroud)
对行进行多次更改后,恢复到原始命令:
revert-line (M-r)
Undo all changes made to this line. This is like
executing the undo command enough times to get back to the beginning.
Run Code Online (Sandbox Code Playgroud)
M
是元键,即 alt</kbd+r for me.
当你已经执行像OP命令以前做(它发生),没有什么可以“撤销”,因为这些命令是由处理和记忆GNU的Readline库,并且不写入$HISTFILE
直到shell退出。我提到这一点的原因是因为你不能只grep
在$HISTFILE
像人们所预料的,它可能不是理想的退出外壳。
所以这里有几个选项可以让您免于回滚以前的所有 readline 命令。
如果您记得某些命令,请按ctrl+r并键入您记得的内容以搜索包含该字符串的先前命令。再次按ctrl+r将显示下一个最近的,向后搜索。
例如,键入ls -l
then ctrl+r查找您要查找的上一个命令所需的次数。如果滚动过去,ctrl+s 将从当前位置向前搜索。
该fc
内建命令的bash是有帮助的列表中的索引号以前一起readline的命令。
fc -l -100
将在 readline 中列出前 100 个命令。
此外,如果 OP 知道他正在寻找以前的ls -l
命令,他可以将输出通过管道传输到grep
例如:fc -l -100 | grep 'ls -l'
这应该输出以ls -l
索引号开头的先前命令的列表。输出如下所示:
2065 ls -l
现在您可以使用事件指示符!n
wheren
是索引号。在这个例子中,执行!2065
将扩展到ls -l
.
虽然没有在事后帮助,任何人都希望修改以前的命令时,应该看到保存最近命令历史记录HISTORY EXPANSION
的部分man bash
。以下是一些修改旧命令而不覆盖历史记录的替代方法。
该Event Designators
部分显示了如何从最近使用的命令轻松编辑字符串。
^string1^string2^
Quick substitution. Repeat the previous command, replacing string1 with string2. Equivalent to
``!!:s/string1/string2/'' (see Modifiers below).
Run Code Online (Sandbox Code Playgroud)
例子:
$ echo foo
foo
$ ^foo^bar
echo bar
bar
Run Code Online (Sandbox Code Playgroud)
最近的命令现在将显示:
echo foo
echo bar
Run Code Online (Sandbox Code Playgroud)
上面的示例还说明了如何使用sed
替换事件指示符中的字符串。
!-n Refer to the current command minus n.
Run Code Online (Sandbox Code Playgroud)
因此,如果历史记录中有 3 个命令,echo foo
那么您将使用:
!-3:s/foo/bar
请注意,事件指示符将作为命令执行出现在您的历史记录中,在本例中为echo bar
。它不会出现在历史记录中!-3:s/foo/bar
。
只是将它扔在那里,因为它似乎密切相关,即使它更像是“不做”而不是 OP 正在寻找的“撤消”解决方案。