问题描述
请查看以下命令:
$ notify-send SYNC TIME!
$ notify-send 'SYNC TIME!'
$ notify-send "SYNC TIME!"
bash: !": event not found
$
前两个命令按预期产生通知气泡。第三个给出显示的错误。
和
$ echo SYNC TIME!
SYNC TIME!
$ echo 'SYNC TIME!'
SYNC TIME!
$ echo "SYNC TIME!"
bash: !": event not found
$
同样在这里,echo
适用于前两个命令,但不适用于第三个命令。
这里还有更多问题(尽管我不打算使用它):notify-send "SYNC!TIME"
和echo "SYNC!TIME"
都给出bash: !TIME": event not found
。
但是notify-send
和echo
均可与"SYNC! TIME"
一起使用
有人可以解释为什么出现bash: !": event not found
错误吗?
最佳办法
!
是Bash中的默认历史记录扩展字符,请参阅Bash manpage中的”HISTORY EXPANSION”部分
-
如果
!
用单引号引起来,则不会进行历史扩展,例如notify-send 'SYNC TIME!'
-
如果
!
后跟一个空格,制表符,换行符,回车符或=
,则不会进行历史记录扩展,如notify-send SYNC TIME!
-
历史扩展确实发生在
echo "SYNC TIME!"
因此,如果您的历史记录中没有以
"
开头的命令,则会出现错误
次佳办法
因为在bash中,!
是保留字(OK,字符),所以它在不同的上下文中具有特殊的含义。在这种情况下,您将无法理解其在历史搜索中的重要性。从man bash
:
History expansions introduce words from the history list into the input
stream, making it easy to repeat commands, insert the arguments to a
previous command into the current input line, or fix errors in previous
commands quickly.
[...]
History expansions are introduced by
the appearance of the history expansion character, which is ! by
default. Only backslash (\) and single quotes can quote the history
expansion character.
基本上,这意味着bash将在!
之后获取字符,并在历史记录中搜索它发现的以这些字符开头的第一个命令。演示比解释容易:
$ echo foo
foo
$ !e
echo foo
foo
!
已激活的历史记录扩展,与第一个以e
开始的命令匹配,该命令是先前运行的echo foo
,然后又运行了。因此,当您编写"SYNC TIME!"
时,bash看到了!"
,在历史记录中搜索了以"
开头的命令,但失败并提出了抱怨。您可以通过运行例如!nocommandstartswiththis
来获得相同的错误。
要打印感叹号,您需要通过以下两种方式之一对其进行转义:
echo 'Hello world!'
echo Hello world\!