Bash 使用感叹号进行历史扩展,如以下问题的答案中所述这个问题(例如,sudo !!
使用 运行先前的命令行sudo
)。但是,我找不到任何地方可以解释运行以下命令(即单个感叹号)的作用:
!
它似乎没有打印任何内容并以 1 退出,但我不确定为什么会这样做。我在网上和 Bash 手册页中查看过,但找不到任何东西,除了它是一个“保留字”这一事实 - 但也是如此}
,并运行以下命令:
}
打印错误:
bash: syntax error near unexpected token `}'
答案1
孤独者!
在命令开始时否定命令或管道的退出状态:如果命令退出0
,它将转变为1
(失败),如果退出非零,它将把它变成0
(成功)退出。
Bash 手册中记录了这种用法:
如果保留字'!'在管道之前,退出状态是上述退出状态的逻辑非。
没有后续命令的A!
会否定空命令,该命令不执行任何操作并返回 true(相当于命令:
)。因此,它将 true 反转为 false 并以状态 1 退出,但不会产生错误。
!
内部还有其他用途test
和[[
命令,它们否定条件测试。这些与你所看到的无关。在您的问题和这些情况下,它与历史扩展无关,并且!
与任何其他术语分开。
答案2
您可以在 bash 手册部分中找到记录的单个感叹号3.2.2 管道
如果保留字'!'在管道之前,退出状态是上述退出状态的逻辑非。
$ ! true; echo $?
1
$ ! false; echo $?
0
!表达
如果表达式为假则为真。
!表达式
如果 expr 为假,则为真。
还应该注意的是,!
除非后面跟有:空格、制表符、行尾、“=”或“(”(当使用内置 shopt 启用 extglob shell 选项时),否则将启动历史替换。
答案3
因为!
用于比较和手段不是。
例如:
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
答案4
!后跟一个字符串,执行以给定字符串开头的最近一条命令(仍在命令缓冲区中)。也许外壳刚刚发现不上一个命令以 <null> 开头。