Bash如何处理双引号内的括号?

4
问题基本上是,bash如何处理双引号和括号?
我想不到更好的例子,所以对此表示歉意,但请想象这样的情况:
“$(echo“ $ {foo}”)”
在那里会发生什么?${foo}在引号范围之外吗?Bash是否足够聪明,还要考虑它是否在括号内,从内向外工作?“$ {foo}”是否更好?
我尝试过谷歌搜索,但没有结果。请注意,这与嵌套引用问题不同,因为它包括扩展。
谢谢!

我有一种感觉你可能理解错了。能否请你阐述一下你的观点? - Jahid
我想要防止单词分割。两次。所以我展示的例子是更复杂的命令调用的一部分。也就是说,我希望$(echo ${foo})的结果被解释为一个单词,但${foo}也应该被解释为一个单词。这主要是出于对bash转义工作方式的好奇,而不是因为我不能通过临时变量等方法解决这个问题。 - spalac24
3个回答

5

每个命令替换都会建立一个新的引号上下文,因此在嵌套的命令替换中避免单词分割的正确方法是使用双引号。

在这个例子中,空格被保留:

$ echo "$(echo "$(echo 'foo     bar')")" # outer echo sees 'foo     bar'
foo     bar

然而,如果缺少任何一个双引号,则该字符串将被Shell分割:

$ echo $(echo "$(echo 'foo     bar')") # outer echo sees 'foo' 'bar'
foo bar
$ echo "$(echo $(echo 'foo     bar'))" # middle echo sees 'foo' 'bar'
foo bar

echo 命令输出每个参数,用空格分隔,这就是 "foo" 和 "bar" 之间的单个空格的来源。


1
这是一个(选择的词不正确,但)编程答案!绝对惊人!赞扬! - William Martens

3
你提供的例子确实能够完全避免单词拆分:
"$(echo "${foo}")"

然而,

"$(echo ${foo})"

这将避免输出时出现单词拆分,但不会对变量$foo产生影响。

$()打开一个子shell,在这个子shell中也需要引用您的变量。考虑以下示例:

"$(echo "$(echo "$foo")")"

以上两对引号都不可省略,如果遗漏任意一对,就会导致单词拆分。

再来看一个例子:

"$foo var in same shell, $(cmd) - this output is also in the same shell"

在上面的代码中,$foocmd的输出是安全的。但如果命令包含在$()中的另一个变量,则该变量将需要加上引号。

2
谢谢!这就是我想表达的,但是其他答案先到了 :/ 很抱歉。 - spalac24
4
@Santiago,这不是竞赛;你应该选择你喜欢的答案并给对你有帮助的答案点赞。 - Tom Fenech

-2

什么是foo?它是一个值吗?尝试一下

"$(echo "$\{foo\}")"

1
什么是“值”?如果你指的是变量,那么是的。为什么你在括号前而不是引号前进行转义?请看我其他的评论以获得澄清:我想防止单词分割。两次。所以我展示的例子是更复杂的命令调用的一部分。也就是说,我希望$(echo ${foo})的结果被解释为一个单词,但${foo}也应该被解释为一个单词。这主要是出于对bash转义工作方式的好奇,而不是我不能通过临时变量等方法解决这个问题。 - spalac24
@Snow,你能否请尽力(或者如果不行的话,请私信我,我可以帮助你构思答案)尝试详细阐述一下,并且写得更多一些(例如包括参考资料,不要用问题回答问题,如果是这样的话-如果不是的话,我很抱歉!)? - William Martens

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