Bash在命令替换中引用

时间:2016-08-17 19:23:13

标签: bash

我很难理解这一点。 以下命令展开文件:

% echo "(echo " * " )"
(echo  foo.txt bar.txt  )

但这不是

% echo "$(echo " * " )"
 * 

Asterisk *未加引号。两种情况都不应该发生文件通配吗?命令替换如何影响这种情况?

2 个答案:

答案 0 :(得分:3)

单独查看命令很有帮助。

% echo "(echo " * " )"

...只有一个引用上下文。在此处引用( echo,不引用*,然后引用)

% echo "$(echo " * " )"

这里,您正在执行命令替换,内部命令具有自己的引用上下文。具体来说,该内部命令是:

# the inner command for the substitution is run first
echo " * "

...正如人们所期望的那样,以*作为输出。值得注意的是,因为它有自己的引用上下文,所以内容开始不加引号,只有在看到"时才会引用。

然后,进行替换; 因为$()在引号内,所以替换过程不会运行字符串拆分和glob扩展(如果遵循这些步骤,则会将内部命令的输出分解为多个单词,并将每个单词扩展为glob)。

echo "$(echo "*")"

...因此变成......

# effectively single-quoted because we already finished running expansions
# so expansions that would be allowed in double-quotes are already finished
echo ' * '

相比之下,如果你没有引用:

echo $(echo "*")

......会变成......

echo *

......其行为符合您的预期。

或者,反过来说

echo "$(echo *)"

......会变成类似于

的东西
echo 'foo.txt bar.txt'

答案 1 :(得分:2)

% echo "$(echo " * " )"
# --------|--------|
#produces |        |
#         echo " * "

引用*

对于您显示的外部echo,引用了cmd替换的输出,您只看到*

也就是说,在执行封闭命令之前处理$( .... )内部的内容。

IHTH