了解bash中的感叹号(!)


108

我用了

history | less

为了获得先前命令的行,并从左侧的数字中发现我要重复的行(例如22),并做了

!22

在命令提示符下,它起作用了-在我当时执行的那一行上执行命令集。我无法弄清楚在何处使用感叹号,根据bash采取的操作,感叹号代表什么,以及在哪里使用。从文档中,我看不到“有形的”解释。


6
这个答案可能会有所帮助
Michael Mrozek

9
不是您的问题的答案,但是<ctrl> + R允许您交互式地搜索历史记录,然后在找到所需内容后立即执行。
kasterma

Answers:


144

!是一项功能,最初出现在C shell中,早在您可以依靠终端获得箭头键的那几天。如果将当前命令编号添加到提示(PS1="\!$ ")中,则特别有用,这样您可以快速查看屏幕以获取过去命令的编号。

既然您可以使用箭头键和类似的功能Ctrl-R来搜索命令历史记录,那么我对该功能的使用并不多。

您可能仍然发现它有用的一个变体是!!,它重新执行上一个命令。就其本身而言,我发现的!!Enter速度并不比快 Enter,但是将其组合成更大的命令时可能会有所帮助。

例如:一个共同的导频误差sudo为基础的系统是忘记sudo上需要额外的特权的指令前缀。新手重新输入整个命令。勤奋的学生会从Shell的命令历史记录中编辑命令。开明的一种sudo !!

Bash允许您!使用set +o histexpand或禁用Shell中的处理set +H。您可以使用在Zsh中禁用它set -K


4
我发现Ctrl-P Ctrl-J非常快;至少比上输入快。
短暂

24
如果只想运行最后一个命令,则Up / Enter很好,但是如果您想以某种方式添加它(例如,您忘记了sudo,或其他东西),则可以这样做sudo !!。这可能比“ Up / Ctrl-A(或Home,如果您足够幸运的话)/ sudo / space / enter”快一点。YMMV。:)

1
@AquariusPower:引用一下。无论是echo 'Hi!'echo "Hi!"echo Hi\!。所有人都做同样的事情。
沃伦·杨

1
setopt NO_BANG_HIST在zsh中,可能比记住更有趣-K
gregory

48

如果这里没有更长的答案,那么我最近就读过一个,因此超级用户肯定有一个答案。在bash手册页中,您可以找到有关此问题的标题为HISTORY EXPANSION的巨大部分。

您可以完成整个主机,而不仅仅是运行最后一个命令或命令号X。您可以执行诸如!cat运行以开头的最后一个命令的操作cat。或!?bash?:s/bash/csh/运行最后一个包含bash但用代替的命令csh


3
尽管不能直接回答OP的问题,但这需要更多的支持。太有用了!谢谢,哈沃克
malvim 2015年

嗯,在开始谷歌搜索之前,我应该真正查看手册页。
erikbwork

1
!!:s/bash/csh/实际上运行最后一个命令,然后将bash替换为csh(如果存在)。不是最后一个包含bash的命令。那可能是!?bash?:s/bash/csh/或也许!?bash?:s/%/csh/
cde

广泛使用Bash已有数年的时间,令我震惊的是,我以前从未听说过该关键字,即使我花了数小时浏览man页面,该功能还是难以理解。感谢您指出相关部分-这是实际文档中唯一可以充分说明这一点的地方。
史蒂夫·本纳


4

我的一个朋友给我发了电子邮件:

它是GNU历史库的一部分。在bash中,它用于重新运行历史记录中的命令。如果您想成为铁杆,请在bash-4.1 / lib / readline / histexpand.c中的history_expansion_char的grep中获取实现细节。


3

当然,您可以!!重用bash shell中的最后一个命令。然后!$可以重用上一个命令的最后一部分。

例如查看一些文件

less path/to/your/file.txt

如果现在要编辑同一文件,则可以使用!$来从上一条命令中仅获取文件路径。

vim !$

1
啊,我希望找到这个。有两个参数怎么办?
乔纳森

它将仅重用两者的最后一个参数。$touch f1 f2然后$vim !$评估为$vim f2
Teshan Shanuka J
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.