以下失败,我不明白为什么:
$ echo "#!"
以下内容也会失败,并显示相同的错误消息:
$ echo "#!"
错误消息:
-bash: !": event not found
为什么会失败?应该如何做echo
?
!
字符用于csh
式历史扩展。
如果不使用此功能,set +o histexpand
(也称为 set +H
(将关闭此行为。 它为脚本关闭,但通常启用交互式使用。 在这种情况下,我个人的建议是通过在您的.bash_profile
中添加set +o histexpand
来永久关闭它(如果您没有.bash_profile
,则.bashrc
;这比我想尝试放入括号更复杂(。
作为一种解决方法,如果由于某种原因您不能或不想关闭并忘记此旧csh
功能,您可以使用单引号而不是双引号 - 当然,请记住它们不同的语义。 例如,如果需要将引用与变量插值相结合,则可以更改
echo "#!$SHELL" # oops, history expansion breaks this
到
echo '#!'"$SHELL"
(注意相邻的单引号和双引号字符串;在 shell 完成此操作后,引号将被删除,字符串#!
将输出在变量SHELL
值旁边,它们之间没有空格(或许多其他常见的解决方法,如
printf '#!%sn' "$SHELL"
。尽管如评论中所述,当它们位于管道末尾时,即使是单引号也不一定会阻止这种情况发生。
默认情况下,bash 支持csh
兼容的历史扩展。
在 bash 中
echo #!
只会打印换行符,因为#
开始注释。
在
echo "#!"
#
是以 "
开头的字符串的一部分。 此类字符串仍然由 bash 检查特殊字符。 !
是一个特殊字符,后面跟着任何其他文本。
-bash: !": event not found
在这种情况下,bash 期望 !"
令牌引用 shell 历史记录中以 "
开头的先前命令,并且找不到。 就其本身而言,!
不会触发此行为:
$ echo # !
# !
$ echo fee ! fie
fee ! fie
最后
$ echo !echo
产生两条线,第一行由外壳打印,以显示上面的图案如何扩展到:
echo echo '# !'
而第二行只是执行扩展命令的结果: 回声#!
另请参阅:关于历史扩展的 Bash 手册页
echo '#!'
基本上,使用双引号("
(又名"弱引号",Bash 对字符串做了一些古怪的事情,比如变量替换。使用单('
(又名"强引用",字符串按字面意思理解。
例如,有关引用的更深入解释,请参阅此处。
另一种解决方法可能是在"!"之后放置一个额外的空格:
# echo "#! "
#!
就我而言,所有命令都正常工作。也许您可以指定您的环境。
$ echo "#!"
#!
$ echo "#!"
echo "#"
#
$ echo "#!"
echo "#"
#
$ echo $BASH_VERSION
3.2.48(1)-release