【问题标题】:echo "#!" fails -- "event not found"回声“#!”失败——“未找到事件”
【发布时间】:2012-08-02 16:57:10
【问题描述】:

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

$ echo "#!"

以下也失败并显示相同的错误消息:

$ echo "\#!"

错误信息:

-bash: !": event not found

为什么会失败? echo 应该怎么做呢?

【问题讨论】:

标签: bash echo


【解决方案1】:

! 字符用于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"

【讨论】:

  • 用@GaborJozan 的回答回滚了编辑,因为那是posted separately,但有一个明显的缺陷是它添加了一个以前没有的空间。
  • 在一些奇怪的情况下,您可以使用单引号代替双引号 except,例如单引号位于管道的下游部分,如 this SO answer 中所述.是的,这有时会令人恼火。如果你不能以其他方式解决它,你可以暂时set +o histexpand
  • 感谢您的评论。我添加了一个部分,强调单引号和双引号之间存在明显差异,并提供了一些解决方法。
  • ... 甚至:echo -e "#\041$SHELL"
  • [bash] "event not found" 上的最佳答案不幸的是不是第一名
【解决方案2】:

默认情况下,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

【讨论】:

    【解决方案3】:
    echo '#!'
    

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

    参见例如here 以获得更深入的引用解释。

    【讨论】:

      【解决方案4】:

      另一种解决方法可能是在“!”之后放置一个额外的空格。 :

      # echo "#! "
      #!
      

      【讨论】:

      • 多年来,这就是我如何解决像 grep -q pattern somefile.txt && echo "YAY! " 这样的单行代码的错误消息(直到今天我才真正理解)。并且可能仍然会,因为 shell 中的双引号字符串只是我的肌肉记忆。
      【解决方案5】:

      在我的情况下,所有命令都在工作。也许你可以指定你的环境。

      $ echo "\#\!"
      \#\!
      $ echo "#!"
      echo "#"
      #
      $ echo "#!"
      echo "#"
      #
      $ echo $BASH_VERSION
      3.2.48(1)-release
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-05-22
        • 1970-01-01
        • 2020-04-22
        • 1970-01-01
        • 1970-01-01
        • 2011-10-02
        • 2012-12-24
        • 2022-07-21
        相关资源
        最近更新 更多