为什么echo "Hello World!"语句不能按预期工作?

3
我正在学习Bash脚本的基础知识。如果我没有弄错的话,没有分隔符并由双引号 ("") 包含的字符串几乎以与字母数字字符串相同的方式进行解释;其中包含的变量将被扩展。另一方面,由单引号(')包含的字符串不会扩展变量,这是与前面提到的字符串的主要区别。
在练习终端时,我注意到一个语句的结果与我的预期不符。您可以在以下示例中看到:
MacBook-Pro-di-Rodolfo:~ Rodolfo$ echo Hello World!
Hello World!
MacBook-Pro-di-Rodolfo:~ Rodolfo$ echo 'Hello World!'
Hello World!
MacBook-Pro-di-Rodolfo:~ Rodolfo$ echo "Hello World!"
echo "Hello World"
Hello World

最后一个语句没有输出与前面相同的字符串,截断了感叹号。有人能解释一下这个字符被删除的原因吗? 如果有用的话,我正在 Mac OS X v. 10.9 下运行所有这些。


2
请查看http://unix.stackexchange.com/q/33339/23529。 - Daniel Jour
@DanielJour,避免这种情况的最优雅解决方案是仅使用单引号,考虑到反斜杠字符在这种情况下不起作用? - rudicangiotti
1
在这里使用转义反斜杠有什么问题吗?如果我没记错的话,bash会将相邻的字符串连接起来,所以类似"Hello World"'!'这样的内容也应该是正确的。 - Daniel Jour
2个回答

4

1
请注意,您可以控制历史记录扩展:使用 set +H 关闭它;使用 set -H 重新启用。 - glenn jackman

3

这真的是一条注释:

引用和非引用字符串存在根本区别:非引用字符串可能会被shell进一步扩展。

单词拆分:非引用字符串将由shell进行标记化,标记将用单个空格连接起来。

text="my name is
   Inigo   Montoya"
echo "$text"
echo $text

输出

my name is
   Inigo   Montoya
my name is Inigo Montoya

注意未加引号的字符串中空格的折叠情况

文件名生成:在未加引号的字符串中,shell文件名模式(也称为“glob”模式)将被扩展:

text="files *"
echo "$text"
echo $text

输出

files *
files [list of all files in your current directory ...]

这种行为可以通过set -fset +f来控制。
要了解所有细节,请阅读bash手册: 此外,这篇文章也很有参考价值:

只是为了好玩:( IFS=''; echo $text ) - gniourf_gniourf
你是指 ( IFS=''; set -f; echo $text )echo "$text" 之间的区别吗?嘿,有趣! - glenn jackman
1
好吧,我真的是没有使用 set -f 的意思,只是为了说明换行符和连续空格被保留了。(当然,所有这些都是一个坏主意,应该在父母监护下使用——除非,当然,我们杀了你的父亲,我们应该准备死亡)。 - gniourf_gniourf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接