【发布时间】:2012-08-02 16:57:10
【问题描述】:
以下失败,我不明白为什么:
$ echo "#!"
以下也失败并显示相同的错误消息:
$ echo "\#!"
错误信息:
-bash: !": event not found
为什么会失败? echo 应该怎么做呢?
【问题讨论】:
-
rici's answer to a duplicate 如果您想要一个详细的、长篇大论的说明,那真是太棒了。
以下失败,我不明白为什么:
$ echo "#!"
以下也失败并显示相同的错误消息:
$ echo "\#!"
错误信息:
-bash: !": event not found
为什么会失败? echo 应该怎么做呢?
【问题讨论】:
! 字符用于csh 样式的历史扩展。
如果您不使用此功能,set +o histexpand(又名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"
【讨论】:
set +o histexpand。
echo -e "#\041$SHELL"
[bash] "event not found" 上的最佳答案不幸的是不是第一名
默认情况下,bash 支持csh 兼容历史扩展。
在 bash 中
echo #!
只会打印一个换行符,因为# 开始一个评论。
在
echo "#!"
# 是以" 开头的字符串的一部分。 bash 仍会检查此类字符串是否有特殊字符。 ! 是一个特殊字符,如果它后跟任何其他文本。
-bash: !": event not found
在这种情况下,bash 期望 !" 令牌引用 shell 历史中以 " 开头的上一个命令,但找不到。 ! 本身不会触发这种行为:
$ echo \# !
# !
$ echo fee ! fie
fee ! fie
最后,
$ echo !echo
产生两行,第一行由shell打印以显示上面的模式如何扩展为:
echo echo '# !'
而第二行只是执行扩展命令的结果: 回声#!
另请参阅:History Expansion 上的 Bash man page
【讨论】:
echo '#!'
基本上,使用双引号 (") 也就是“弱引用”,Bash 对字符串做了一些古怪的事情,比如变量替换。使用单个 (') 又名“强引用”,字符串按字面意思理解。
参见例如here 以获得更深入的引用解释。
【讨论】:
另一种解决方法可能是在“!”之后放置一个额外的空格。 :
# echo "#! "
#!
【讨论】:
grep -q pattern somefile.txt && echo "YAY! " 这样的单行代码的错误消息(直到今天我才真正理解)。并且可能仍然会,因为 shell 中的双引号字符串只是我的肌肉记忆。
在我的情况下,所有命令都在工作。也许你可以指定你的环境。
$ echo "\#\!"
\#\!
$ echo "#!"
echo "#"
#
$ echo "#!"
echo "#"
#
$ echo $BASH_VERSION
3.2.48(1)-release
【讨论】: