我很难理解这一点。 以下命令展开文件:
% echo "(echo " * " )"
(echo foo.txt bar.txt )
但这不是
% echo "$(echo " * " )"
*
Asterisk *未加引号。两种情况都不应该发生文件通配吗?命令替换如何影响这种情况?
答案 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