进程替换是否需要双引号?

进程替换是否需要双引号?

双引号命令替换是一个很好的做法。进程替换(<()和)是否相同>()

双引号似乎允许命令替换,但不允许进程替换:

$ echo <(printf "%s" hello)
/dev/fd/63
$ echo "<(printf "%s" hello)"
<(printf %s hello)

如果任何进程替换的结果包含空格,或者这种情况从未发生过怎么办?

谢谢。

答案1

引用过程替换会抑制它,正如经过简单测试的那样:

$ echo <(echo 123)
/dev/fd/63
$ cat <(echo 123)
123
$ echo "<(echo 123)"
<(echo 123)
$ cat "<(echo 123)"
cat: '<(echo 123)': No such file or directory

对我来说很奇怪的是,你在提出问题之前没有尝试这样做,但现在至少很容易验证它不会起作用。

这与引用其他 shell 操作符时发生的情况没有什么不同;echo "("出于同样的原因,这不是语法错误,也不会给echo "> /dev/sda"您带来任何问题。

记录在案行为是:

该文件名作为扩展结果作为参数传递给当前命令

作为单个参数,空格的存在或不存在并不重要,并且分词不相关且不执行。在某些平台上,生成的路径中可能出现空格,但这不会产生影响。

答案2

在 bash 中,当字符串被括起来时双引号,它被解释为文字,除非至少涉及以下特殊字符之一:

$ ` \ ! * @

<(command_list)无法在双引号内解释进程替换的语法。不涉及任何将被解释为文字以外的任何字符。双引号必须防止进程替换,因为它不允许解释其语法。

命令替换的语法是:

$(command)
# or
`command`

这两个字符都以双引号($或反引号)内的特殊字符开头,并且如您所知,双引号不会抑制命令替换。

当您想要预测双引号是否会抑制某些行为时,这通常是一个很好的首要考虑规则。如果语法不涉及这 6 个字符之一,则双引号必须抑制它(大括号扩展、波形符扩展、进程替换、 上的分词,这些都不能出现在双引号内)。当然,并非所有涉及这六个字符之一的语法都出现在双引号内,但这是一个需要考虑的良好的首要规则。这个答案和规则旨在帮助您在遇到并记住所有情况之前做出预测。如果无法解释双引号内的语法,则该行为不会发生。

相关内容