在 UNIX 系统中,您可以按顶部和底部箭头浏览之前的命令。这非常方便。
有时,我会找到一个我想再次使用的命令,但有一些变化。如果我做了这样的更改,那么我没有办法取回原始命令,除非我将其签入history
.
有没有办法“撤消”通过按键访问的历史记录中命令的更改?
#
我当前的解决方法是在命令前面添加 a 。这样当前命令将作为注释执行,因此不会发生任何事情。然后,我可以再次使用按键浏览命令。问题是我使用的命令可能在列表中距离很远,所以再次向上移动 200 次就有点了。 Control + R 也不是一个解决方案,因为我可能不记得我到底在寻找什么。
例子
我输入了以下“50 个命令前”:
ls -l /etc/httpd/conf/
现在我走到那条线并将其更改为
ls -l /etc/init.d/
但没有按回车键。现在,我想再说ls -l /etc/httpd/conf/
一遍。
我的环境
$ echo $SHELL
/bin/bash
$ echo $TERM
xterm
答案1
只要您编辑了历史记录条目但尚未按下Enter,要返回到原始条目,请重复按Ctrl+ _(该undo
命令),直到不再进行任何进一步的更改。您返回到原始条目。
答案2
恢复到原来的命令当您对该行进行了多次更改时:
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.
M
是元键,即alt</kbd+r for me.
无偿但有用的信息
当你有执行了像OP之前所做的命令(它发生了),没有什么可以“撤消”,因为命令是由GNU 阅读线图书馆和是没有写信给$HISTFILE
直到 shell 退出。我之所以提到这一点,是因为您不能像人们所期望的grep
那样$HISTFILE
,并且退出 shell 可能并不理想。
因此,这里有几个选项可以帮助您避免向后滚动所有以前的 readline 命令。
如果你还记得一些命令,按ctrl+r并输入您记得的内容搜索以前的命令包含该字符串。再次按ctrl+r将显示下一个最新的向后搜索。
例如,键入ls -l
then ctrl+r多次,以查找您要查找的上一个命令。如果滚动过去,ctrl+s 将从当前位置向前搜索。
bashfc
内置命令与之前的 readline 命令一起列出索引号很有帮助。
fc -l -100
将列出 readline 中之前的 100 个命令。
此外,如果 OP 知道他正在寻找上一个ls -l
命令,他可以将输出通过管道传输grep
到:fc -l -100 | grep 'ls -l'
这应该输出先前命令的列表,ls -l
前面带有索引号。输出如下所示:
2065 ls -l
现在您可以使用事件指示符,!n
其中n
是索引号。在此示例中,执行!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).
例子:
$ echo foo
foo
$ ^foo^bar
echo bar
bar
最近的命令现在将显示:
echo foo
echo bar
上面的示例还解释了如何使用sed
替换事件指示符中的字符串。
!-n Refer to the current command minus n.
因此,如果历史记录中有 3 个命令,echo foo
那么您将使用:
!-3:s/foo/bar
请注意,事件指示符将在执行命令时出现在您的历史记录中,在本例中为echo bar
。它不会作为 出现在历史中!-3:s/foo/bar
。
只是把它扔在那里,因为它看起来密切相关,即使它更像是“不做”而不是OP正在寻找的“撤消”解决方案。
答案3
读取行变量revert-all-at-newline
从 Bash 4.0/Readline 6.0 开始可用,几乎达到了预期的效果。
如果设置,则在任何行(可能是不同的命令,甚至空行)上按 Enter 键将恢复已编辑但未执行的任何历史记录条目(如问题中的示例所示)。
这可以设置为
set revert-all-at-newline on
在~/.inputrc
。
或者
bind 'set revert-all-at-newline on'
在~/.bashrc
。