Bash 引号在命令替换时未转义

use*_*268 3 linux unix script bash shell-script

有人可以解释我为什么这样做(列出名称中包含空格的目录的内容):

ret="$(ls "my dir")"
Run Code Online (Sandbox Code Playgroud)

它不应该被解释为:

ret="$(ls "
my dir
")"
Run Code Online (Sandbox Code Playgroud)

例如:

ls "my" "dir"
Run Code Online (Sandbox Code Playgroud)

ls "my dir"
Run Code Online (Sandbox Code Playgroud)

G-M*_*ca' 6

到目前为止最好的猜测似乎是你在问:

命令

    ret="$(ls "我的目录")"

是一个包含四个双引号 ( ") 标记的命令的非常糟糕的示例。?人们可能天真地认为第二个引用会与第一个匹配,而第四个会与第三个匹配,如下所示:

    ret="$(ls "my dir")"
        ?-----?      ?-?
Run Code Online (Sandbox Code Playgroud)

例如,发生在

    eat "afternoon snack" dinner "midnight snack"
Run Code Online (Sandbox Code Playgroud)

相反,它“有效”,如下所示:

    ret="$(ls "我的目录")"
        ? ?------? ?
        ?--------------?

为什么嵌套引号以这种方式解析?

这一段bash(1) 可以解释一下:

命令替换

                        ?
    ... 使用表格时,括号之间的所有字符组成命令 ...。$(command)

我想这意味着您所观察到的,即,将 the$(和 the之间的文本)视为一个单独的命令,具有自己的解析/引号配对,独立于括号外的句法元素。我承认,如果你不是在寻找那个意思,就很难解释。


但是你写的问题没有意义。整个事情取决于对$外壳的非常特殊的含义。如果我们将其更改为其他货币符号,

    ret="£(ls "my dir")"
Run Code Online (Sandbox Code Playgroud)

那么它将被视为两个词:

        ret="£(ls "my
(其次是)
                                    dir")"

因为,如果一个非空白的、非特殊的字符出现在开始引号之前或结束引号之后,它会包含在与引号中的字符相同的字符串中。例如,

    ret="$(ls "my dir")"

寻找一个名为 的文件Wal*mart,而不是一个名为 的文件Wal,一个叫*,一个叫martWal"*"mart等价于Wal\*mart"Wal*mart"。同样,以下示例显示了四个单词:

    一个”“两个扣”我的“鞋子/don\'t/be/a/”“/cadet sqrt”(2)”
    ? -------??--------------??--------------------?? -------?

我不知道你从哪里得到了你在问题中显示的三行细分。