请看一下这些命令:
$ 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
会出现这个错误吗?
答案1
!
是 Bash 中的默认历史扩展字符,请参阅Bash 手册页
如果用单引号引起来,则不会进行历史扩展
!
,例如notify-send 'SYNC TIME!'
!
如果 后面跟着空格、制表符、换行符、回车符或=
,则不会进行历史记录扩展,例如notify-send SYNC TIME!
历史扩展做发生在
echo "SYNC TIME!"
"
因此,如果历史记录中没有以 开头的命令,则会收到错误
答案2
因为在 bash 中,!
是一个保留字(好吧,字符),它在不同的上下文中具有特殊含义。在这个特定情况下,您与它在历史搜索中的重要性相冲突。来自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\!