如何搜索bash历史记录并重新运行命令?


Answers:


428

键入Ctrl R的命令行并开始输入一条命令。一旦出现结果Ctrl R,请继续点击以查看其他匹配项。出现所需命令时,只需按Enter

请注意,虽然while Ctrl R是默认设置,但是如果您想reverse-search-history绑定命令(),则可以Ctrl T使用以下命令进行配置:

绑定'“ \ Ct”:反向搜索历史'

您还可以使用许多其他的readline可绑定命令。看一下bash手册页

Bash具有许多功能来搜索和访问交互式命令历史记录。其中最基本的是history内置的。只是输入:

$历史

将打印命令列表以及数字索引,例如:

$历史
1清除
2 ls -al
3 vim〜/ somefile.txt
4历史
$

然后,您可以使用它们的数字索引来执行这些命令中的任何一个!,方法是在索引的前面加上单个,如Mitch所指出的:

$!1

将执行clear命令。内置的历史记录本身具有许多功能,您可以在bashhistory手册页中看到更多信息。

您还可以在使用!指示符时指定相对负偏移量,因此,使用上面的历史记录列表,如果我们想vim再次执行,可以执行以下操作:

$!-2

基本上,这是告诉bash执行您在“两个命令之前”运行的命令。要在历史记录列表中运行上一个命令,我们可以使用!!(这只是的简写!-1)。

!标志不限制你数值指定要运行的命令。hayalci显示,您可以指示bash基于命令开头的文本(使用!)或命令本身内的文本(使用)执行命令!?。再次使用上面的示例历史记录列表,如果我们想clear再次执行,则只需输入:

$!cl

然后按Enter。那又如何vim呢?这很简单:

$!?一些

hayalci的响应中最重要的一点是对shopt内建函数的调用:

$ shopt -s histverify

这将使历史的验证,使得被匹配的命令!!!以及!?代号并不是盲目地执行,而是填充在命令行上,这样可以保证他们在执行之前不做坏事。当您以root用户身份执行命令时,这一点尤为重要。可以在.bashrc启动文件中设置此选项,以便在您每次登录时都进行设置。

正如已经指出的那样,所有这些信息都可以从bash手册页中获取。对于!,!!和!?请参阅9.3节“ 历史扩展”


39
+1我在所有系统上使用Linux已有12年以上。我不知道那个存在。希望我能+10我怎么想念它?
艾登·贝尔

1
在许多系统上,按向上箭头也可以这样做。
mas

如果有人要合并“!”,“ !!”,“ !?”,“历史记录| grep”和“ ctrl-r”作为一个全面的答案,我会选择它
Richard Hoskins

shopt放在bashrc中,而不是bash_profile中(否则,不是登录shell的shell不会启用它)。
东武

2
同样,在按CTRL + R之后,您可以多次使用CTRL + SHIFT + R跳回到上一个命令
Gal Bracha 2015年

37

作为的替代方法crtl+R,您可以输入以下内容来搜索历史记录:

!text

这将在历史记录中搜索以“ text” 开头的最新命令。

但是我建议您将其放在.bashrc中,以防止执行错误的命令。

shopt -s histverify

这会指示bash,以便在执行任何历史记录操作(如!!:s/prev_text/after_text)之后,将结果行放置到命令提示符下。然后,您可以查看或编辑命令,然后按Enter。


5
使用!?text重新执行包含(而不是开头)“ text”的最新命令。
mark4o

3
如果有人要合并“!”,“ !!”,“ !?”,“历史记录| grep”和“ ctrl-r”合并成一个完整的答案,我会选择它。
理查德·霍斯金斯

32

您也可以这样做:

history | grep "stuff"

它会返回类似

num stuff

然后你可以输入

!num

15

我更喜欢使用向后搜索历史记录而不是反向搜索历史记录。前者使您可以键入命令的几个字符,然后按搜索键,而不是先按搜索键然后输入搜索字符串。

在我的系统上,默认情况下,Mp和Mn绑定到相似的功能,但是我更喜欢绑定箭头键:

bind '"\e[A":history-search-backward'
bind '"\e[B":history-search-forward'

13

我有一个很好的别名,h。它实际上只是“历史记录| grep”,但我使用“ grep -E -v”过滤掉了先前的“ h命令”条目

alias h="history | grep -E -v '^ *[0-9]+ *h ' | grep "

使用像

h aliases
2003  less .bash_aliases

1
也可以通过将命令添加到来完成HISTIGNORE
tanenbring

12

出色的写作,肖恩!我将其添加到评论中,但我有些害羞。:-)

另一个相关且有用的技术是能够在更改单词时运行先前的命令。假设您输入了目录名,或者要更改文件名:

$ echo我的名字叫鲍勃
我的名字是鲍勃
$ ^ bob ^ jordan
呼应我的名字叫乔丹
我的名字叫乔丹

请注意,该命令在运行之前会被扩展,替换和输出,因此,如果运行了错误的命令,您可以看到bash认为它在做什么。


6

由于使用Ctrl-r在历史记录中导航非常麻烦,因此您可能需要考虑hh

https://github.com/dvorka/hstr

这使导航更加简单,直接和高效-包括运行以下命令:

在此处输入图片说明


如何使用它?按下哪个键才能看到此图片?
Nakilon'3

2
安装hh后,您可以使用hh命令,也可以将其绑定到文档中所述的任何键盘快捷键(通常为Ctrl-r)。
Martin Dvorak

ctrl + r现在默认绑定到
-Alleo

4

在bash命令提示符下,键入control-R,然后键入所需命令的几个字符,bash的readline工具将在命令历史记录中搜索该命令。

开始搜索后,可以再次键入control-R以跳到下一个匹配的命令。


3

如果您已将外壳配置为使用vi键绑定(set -o vi或使用set editing-mode viin $HOME/.inputrc),则可以使用搜索<Esc>/some-command<Return>并单击n(下一个)或Shift-n(上一个)以循环浏览命令行历史记录。


这是最接近vim用户的。
加博尔·马顿

2

CTRL+ R可以正常工作,就像@ John1024所建议的那样,但是如果您最近使用的许多命令都相似并且您想要一种快速的方法来扫描所有命令,则有些麻烦。一种替代方法是使用history

$ history | grep keyword

0

我喜欢HSTR,但有时似乎无法安装。因此,我使用fzf编写了一个别名来模仿其行为(hx,用于“历史执行”)

alias hx='eval $(history | sed "s/^ *[0-9]* *//g" | fzf --tac --tiebreak=index --height=10)'
  • history :好吧,获取历史
  • sed :从列表中删除数字列(POSIX)
  • fzf:这是神奇的法宝,允许您交互式地模糊搜索列表,或使用C-J和移动C-K,然后使用来执行命令Enter
  • --height :设置显示的行数。
  • --tac :还原列表(对于历史记录更合乎逻辑)
  • --tiebreak=index :保留fzf更新结果时的历史记录顺序
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.