为什么我不能回应“!”在bash?

时间:2014-01-27 11:17:15

标签: linux bash

我刚才尝试了以下内容:

echo "Hello World!" > hw.txt

我收到了这个错误:

bash: !": event not found

我尝试了escaping这样的!

echo "Hello World\!" > hw.txt

hw.txt包含:

Hello World\!

现在我试过了:

echo "Hello!World" > hw.txt

我得到了这个:

bash: !World": event not found

但是当我尝试这个时:

echo "Hello ! World" > hw.txt

令我惊讶的是它有效!

所以我尝试了这一点:(注意最后的space。)

echo "Hello World! " > hw.txt

为什么bash会像这样对待!,甚至在引号内?它如何与trailing space一起使用?我错过了一些明显的东西吗?

3 个答案:

答案 0 :(得分:3)

此行为在 HISTORY EXPANSION 部分下的bash手册页中指定:

  

历史的扩展是由历史的出现引入的   扩展字符,默认为!。只有反斜杠(\)和   单引号可以引用历史扩展字符。

     

如果立即发现,有几个字符会阻止历史扩展   遵循历史扩展字符,即使它没有引用:   空格,制表符,换行符,回车符和=。如果是extglob shell   选项已启用,(也将禁止扩展。

  

如果启用,则除非出现!,否则将执行历史记录扩展   在双引号中使用反斜杠进行转义。反斜杠   <{1}}之前的内容未被移除。

答案 1 :(得分:3)

对不应插入的字符串使用单引号:

echo '!'

对可以插入的字符串使用双引号:

echo "$PWD"

答案 2 :(得分:2)

尾随空格禁用Bash事件指示符!

man bash | less -Ip 'Event Designators'

# An  event designator is a reference to a command line entry in the his-
# tory list.  Unless the reference is absolute, events  are  relative  to
# the current position in the history list.
# 
# !     Start  a  history substitution, except when followed by a blank,
#       newline, carriage return, = or ( (when the extglob shell  option
#       is enabled using the shopt builtin).

禁用事件指示符!的另一种方法是使用:

set +H  # ... or ...
set +o histexpand
help set