在Bash中键入单个感叹号有什么作用?


20

Bash使用惊叹号扩展历史记录,如对此问题的答案所述(例如,使用来sudo !!运行先前的命令行sudo)。但是,我找不到任何地方可以解释运行以下命令(即单个感叹号)的作用:

!

它似乎什么也没打印,并以1退出,但是我不确定为什么要这样做。我已经在网上和Bash手册页中进行了查找,但是除了它是一个“保留字”这一事实外,什么都找不到,但是},并运行以下命令:

}

打印错误:

bash: syntax error near unexpected token `}'

1
没有。!表示历史扩展表达式的“开始”。
jordanm

Answers:


47

!命令开始处的孤行会否定命令或管道的退出状态:如果命令退出0,它将翻转为1(失败),如果退出非零,则将其变为0(成功)退出。

Bash手册中记录了这种用法:

如果保留字为“!” 在管道之前,退出状态是如上所述退出状态的逻辑取反。

一个!没有下面的命令否定了空命令,该命令不执行任何操作,并返回true(相当于:命令)。因此,它将true转换为false并以状态1退出,但不会产生错误。


还有的其它用途!的内test[[命令,在那里他们否定条件测试。这些与您所看到的无关。在您的问题和这些情况下,它都与历史记录扩展无关,并且与!其他任何术语都分开。


5
+1作为第一个答案,以解释实际运行的内容以及为什么解释返回代码。
Jeff Schaller

11

您可以在bash手册第3.2.2节“ 管道”中找到记录的单个感叹号

如果保留字为“!” 在管道之前,退出状态是如上所述退出状态的逻辑取反。

$ ! true; echo $?
1
$ ! false; echo $?
0

以及第3.2.4.2条件构造

!表达

如果表达式为假,则为真。


以及第4.1Bourne Shell Builtins

!expr

如果expr为假,则为True。


还应该注意的是,!将开始历史记录替换,除非后面跟有:空格,制表符,行的结尾,'='或'('(当使用内置的shopt启用extglob shell选项时)。


0

因为!用于比较中,表示NOT

例如:

a=3
b=2

[ $a -eq $b ] && echo "Equal"
[ ! $a -eq $b ] && echo "Not equal"
# of cause last comparison is possible to write as:
[ $a -eq $b ] || echo "Not equal"

[ $a -eq $b ]
echo $?
1
[ ! $a -eq $b ]
echo $?
0

1
这就是!作为test命令参数(包括bash的内置版本)的含义,而不是!在命令位置使用的含义。
吉尔斯(Gilles)'所以

1
! [...]在这种情况下,需要匹配该问题。
Michael Homer

同意@Gilles和@Michael Homer。我知道那[]test。我有点着急。
Yurij Goncharuk '18

-2

! 内置命令,反转管道感。

其他用途:

#! 内置命令,调用命名解释器以执行脚本。

! 事件指示符,将命令行单词标记为历史记录替换

!= 不等式算子

$! shell变量,返回上一个后台命令的进程号。


只需添加一下,您就可以使用!$来使用上一个命令的最后一个单词,如下所示: ls -l /tmp cd !$ 这将带您进入/ tmp目录。
跳兔子

-3

!紧跟着一个字符串的字符串将执行以给定字符串开头的最近的上一条命令(仍在命令缓冲区中)。也许shell只是发现以前的命令都没有以<null>开头。


3
您注意到问题中没有给定的字符串...?
Jeff Schaller
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.