为什么我不能使用“!”当尝试在终端中回显消息时?例如:
echo -e "Hello\nWorld!"
bash 返回以下命令:
bash !: event not found
答案1
这个!
角色被称为“bang”,bash
用它来回忆命令历史。您可以通过四种方式使用它:
!<firstFewCharsOfPreviousCommand>
例子:
!rm
这将转到您执行的最后一个以“rm”开头的命令并执行整个命令。是小心当重复诸如 rm 之类的潜在破坏性命令时,您可能会无意中执行超出您预期的另一命令。上面只是说明,使用 bash 的CTRL-R
反向搜索功能是一个更安全的选择。
!<indexInCommandHistory>
例子:
!433
索引是运行命令时显示在命令旁边的数字history
。
!!
不需要示例,因为这就是全部。它重新执行前一个命令(与大多数 Linux 发行版上的向上箭头相同)。
!$
例子:
# ls -lh /etc/fstab
# vi !$
另一个文字,当 bash 执行它时, the!$
被最后一个单词替换(没有空格的字符串)
正如您在最后一个命令中所看到的,您甚至可以将其用作更大或不同命令的一部分。另一个例子!!
:
[root@hypervisor libsceptre]# echo hey
hey
[root@hypervisor libsceptre]# echo !!
echo echo hey <-- printed to stderr so you know what !! was expanded to
echo hey
[root@hypervisor libsceptre]#
如果您希望 bash 无论出于何种原因将字符视为文字而不是尝试解释它,您可以将文本放在单引号中:
[root@hypervisor libsceptre]# echo -e "Hello\nWorld!"
-bash: !": event not found
[root@hypervisor libsceptre]# echo -e 'Hello\nWorld!'
Hello
World!
[root@hypervisor libsceptre]#
您的命令不起作用的原因是它试图查找您编写的以双引号开头的最后一个命令(我的第一个示例中描述的功能),但找不到它。
答案2
如果您不使用历史扩展(而且您显然不这样做),那么您应该禁用它,而不是学习奇怪的引用和抑制规则。
set +H
或者set +o histexpand
让你摆脱它。您可以通过echo $-
(“H”表示处于活动状态)或set -o
( )来检查它是否处于活动状态histexpand
。
答案3
你需要逃离爆炸:
echo -e "Hello\nWorld"\!
笔记:在引号之外加上爆炸是故意的。否则\!
是回声。
答案4
双引号内的特殊含义!
仍然有效。!
是一个 shell 关键字,例如,它采用整数 n 作为参数并运行 shell 历史记录中的第 n 个命令。使用单引号或转义字符以避免混淆。
您可以在 中阅读有关历史命令扩展的更多信息man history
。