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