回声"#!" 失败 - "未找到事件"

eri*_*ork 13 bash echo ubuntu-12.04

以下失败,我不明白为什么:

$ echo "#!"
Run Code Online (Sandbox Code Playgroud)

以下也失败并出现相同的错误消息:

$ echo "\#!"
Run Code Online (Sandbox Code Playgroud)

错误信息:

-bash: !": event not found
Run Code Online (Sandbox Code Playgroud)

为什么会失败?该怎么echo办呢?

tri*_*eee 14

!角色用于csh风格的历史扩展.

如果您不使用此功能,set +o histexpand(aka set +H)将关闭此行为.它已关闭脚本,但通常启用交互式使用.

作为一种解决方法,您可以使用单引号而不是双引号 - 当然,请记住它们的不同语义.例如,如果需要将引用与变量插值相结合,则可以进行更改

echo "#!$SHELL"  # oops, history expansion breaks this
Run Code Online (Sandbox Code Playgroud)

 echo '#!'"$SHELL"
Run Code Online (Sandbox Code Playgroud)

(注意相邻的单引号和双引号字符串;在shell完成之后,引号将被删除,字符串set +o histexpand将输出到变量的值旁边,.bash_profile它们之间没有空格)或其他一些常见的解决方法就像

 printf '#!%s\n' "$SHELL"
Run Code Online (Sandbox Code Playgroud)


Hen*_*eld 9

默认情况下,bash支持csh兼容的历史记录扩展.

在bash中

echo #!
Run Code Online (Sandbox Code Playgroud)

只会打印换行符,因为它会#开始发表评论.

echo "#!"
Run Code Online (Sandbox Code Playgroud)

#是字符串的一部分开始".对于特殊字符,bash仍会检查此类字符串. !如果后跟任何其他文本,则为特殊字符.

-bash: !": event not found
Run Code Online (Sandbox Code Playgroud)

在这种情况下,bash期望!"令牌引用shell历史记录中以前的命令",但不会找到.所有这些!都不会触发此行为:

$ echo \# !
# !

$ echo fee ! fie
fee ! fie
Run Code Online (Sandbox Code Playgroud)

最后,

$ echo !echo
Run Code Online (Sandbox Code Playgroud)

生成两行,第一行由shell打印,以显示上面的图案如何扩展为:

echo echo '# !'
Run Code Online (Sandbox Code Playgroud)

而第二行只是执行扩展命令的结果:echo#!


参见:猛砸男子页上的历史扩展


Sta*_*ven 5

echo '#!'
Run Code Online (Sandbox Code Playgroud)

基本上,使用双引号 ( ") 又名“弱引用”,Bash 对字符串做了一些古怪的事情,比如变量替换。单 ( ') 又名“强引用”,字符串按字面意思表示。

有关引用的更深入解释,请参见例如此处