如果我输入:
echo "Hello, World!"
我不知道它的名字,但它提示我输入下一行。你知道这PS2
件事。或者,如果您键入echo \
并按Enter
。
为什么?
嗯,我知道那!
是一个特殊变量您可以用它参考您的历史记录。
但一旦我使用这个:
echo "Hello, World"!
我得到了我想要的输出。发生了什么事,为什么不能!
在内部使用""
?
感谢您的帮助 :)
答案1
!
不是特殊的_变量。 (有一个名为 的变量!
,您可以使用 访问它$!
,但它是不相关的。)它是一个具有特殊含义的字符,具体取决于 bash 在哪里看到它以及后面的内容。
角色!
开始历史扩展。 Bash 在解析命令行时,当它以交互方式读取命令时(不是在运行脚本时,甚至是来自交互式命令行的脚本),很早就执行历史.
扩展source
。您可以设置变量histchars
选择不同的字符代替!
(但大多数其他 ASCII 字符会与常见用法发生冲突)。
人物!
开始历史替换
除非后面跟有空格、制表符、行尾、“=”或“(”(当使用内置 shopt 启用 extglob shell 选项时)。
echo "Hello, world"!
所以像or 之类的事情if ! grep -q foo myfile; …
不会触发任何历史扩展。
还单引号和美元单引号防止历史扩展(即历史扩展字符在 内时没有其特殊含义'…'
),并且引用字符的反斜杠可以保护该字符免于启动历史扩展,但是双引号不,除了(从 bash 4.4 开始),当 bash 在 POSIX 兼容模式下调用时。也就是说,默认情况下,
echo "!foo"
制作!foo
一个历史参考,该参考被替换在双引号内。您不能简单地在双引号字符串中包含实际的感叹号,因为其中echo "\!foo"
会包含反斜杠。你必须使用类似echo \!"foo"
或 的东西echo '!foo'
。我不知道 bash 为何这样做:这是 20 世纪 80 年代做出的设计决策。 (Bash 从 csh 继承了历史扩展,但情况更糟:即使是单引号也不能防止历史扩展。)
但我无法重现这个确切的情况:
bash-5.0$ echo "Hello, World!"
Hello, World!
但这可能取决于 bash 的版本或配置。双引号本身并不会抑制历史扩展:事实上,它!"
不适合任何形式事件指示符。
bash-5.0$ echo "Hello!world"
bash: !world: event not found`
答案2
假设您使用bash
as 标记,请使用单引号而不是双引号
echo 'Hello, World!'
Hello, World!
不过,我认为您更有可能使用zsh
,并且适用相同的修复:
echo "Hello, World!"
dquote>
echo 'Hello, World!'
Hello, World!
看shell 中的 "..."、'...'、$'...' 和 $"..." 引号之间有什么区别?有关不同类型的报价以及何时(不)使用它们的更多信息。