shell 命令替换中的意外行为

use*_*217 6 shell

鉴于shell脚本 test.sh

for var in "$@"
do
    echo "$var"
done
Run Code Online (Sandbox Code Playgroud)

和调用 sh test.sh $(echo '"hello " "hi and bye"')

我希望输出

hello
hi and bye
Run Code Online (Sandbox Code Playgroud)

而是得到:

"hello
"
"hi
and
bye"
Run Code Online (Sandbox Code Playgroud)

如果我改为 sh test.sh $(echo "hello " "hi and bye")

然后我得到

hello
hi
and
bye
Run Code Online (Sandbox Code Playgroud)

这些行为都不是所期望的,我怎样才能获得所需的行为?

我想了解的是为什么sh test.sh $(echo "hello " "hi and bye")sh test.sh "hello " "hi and bye"不等价?

Kus*_*nda 8

您的命令替换将生成一个字符串。

如果是

$(echo '"hello " "hi and bye"')
Run Code Online (Sandbox Code Playgroud)

这个字符串将是"hello " "hi and bye".

然后该字符串进行分词(和文件名通配,但不影响此示例)。单词拆分发生在与其中一个字符相同的每个字符上$IFS(默认情况下,空格、制表符和换行符)。

由默认值所产生的话IFS"hello""hiand,和bye"

然后将它们作为单独的参数提供给您的脚本。

在您的第二个命令中,命令替换是

$(echo "hello " "hi and bye")
Run Code Online (Sandbox Code Playgroud)

这将生成字符串hello hi and bye和分词会导致四个字hellohiand,和bye

在您的最后一个示例中,您使用两个参数hellohi and bye直接与您的脚本一起使用。这些不会进行分词,因为它们被引用。