Bash кавычки не экранируются при замене команд

Bash кавычки не экранируются при замене команд

Может ли кто-нибудь объяснить мне, почему это работает (перечисление содержимого каталога, в имени которого есть пробел):

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

Не следует ли это интерпретировать как:

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

Как, например, с:

ls "my" "dir"

и

ls "my dir"

решение1

На данный момент наиболее вероятным кажется следующий вопрос:

Команда

    ret="$(ls "мой каталог")"

довольно ужасный пример команды, которая содержит четыре двойных кавычки ( "). Можно было бы наивно ожидать, что вторая кавычка будет соответствовать первой, а четвертая — третьей, вот так:

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

как, например, это происходит с

    eat "afternoon snack" dinner "midnight snack"

Вместо этого он «работает» следующим образом:

    ret="$(ls "мой каталог")"
        ↑ ↑------↑ ↑
        ↑--------------↑

Почему вложенные кавычки анализируются именно таким образом?

Этот абзацбаш(1) может объяснить это:

Замена команды

                        ⋮
    … При использовании формы все символы в скобках составляют команду ….$(command)

Я полагаю, это означает то, что вы наблюдали, а именно, текст между the $(и the )обрабатывается так, как будто это отдельная команда, со своим собственным разбором/парами кавычек, независимо от синтаксических элементов за пределами скобок. Я признаю, что если вы не ищете этот смысл, его очень трудно интерпретировать.


Но ваш вопрос, как он написан, не имеет смысла. Все дело в очень специальном значении(ях) $оболочки. Если бы мы изменили это на какой-то другой символ валюты,

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

тогда это будет рассматриваться как два слова:

        ret="£(ls "my
(с последующим)
                                    dir")"

потому что, если непустой, не специальный символ появляется непосредственно перед открывающей кавычкой или непосредственно после закрывающей кавычки, он включается в ту же строку, что и символы, заключенные в кавычки. Например,

    cat Wal"*"mart

ищет файл с именем Wal*mart, а не файл с именем Wal, один с именем *, и один с именем martWal"*"martэквивалентно Wal\*martи "Wal*mart". Аналогично, следующий пример показывает четыре слова:

    один" "два" пряжки мой "ботинок /не/будь/" "/кадетский квадрат"(2)"
    ↑-------↑ ↑-------------↑ ↑--------------------↑ ↑-------↑

Я не знаю, откуда вы взяли трехстрочную разбивку, которую привели в своем вопросе.

Связанный контент