Citações Bash sem escape na substituição de comando

Citações Bash sem escape na substituição de comando

Alguém pode me explicar por que isso está funcionando (listando o conteúdo de um diretório que possui um espaço em branco no nome):

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

Não deveria ser interpretado como:

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

Como por exemplo com:

ls "my" "dir"

e

ls "my dir"

Responder1

O melhor palpite até agora parece ser que você está perguntando:

O comando

    ret="$(ls "meu diretório")"

é um exemplo terrível de um comando que contém quatro aspas duplas ( "). Poderíamos ingenuamente esperar que a segunda citação correspondesse à primeira, e a quarta correspondesse à terceira, assim:

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

como, por exemplo, acontece com

    eat "afternoon snack" dinner "midnight snack"

Em vez disso, “funciona”, da seguinte forma:

    ret="$(ls "meu diretório")"
        ↑ ↑------↑ ↑
        ↑--------------↑

Por que as aspas aninhadas são analisadas dessa maneira?

Este parágrafo defestança(1) pode explicar:

Substituição de comando

                        ⋮
    … Ao utilizar o formulário, todos os caracteres entre parênteses compõem o comando….$(command)

Acho que isso significa o que você observou, ou seja, o texto entre the $(e the )é tratado como se fosse um comando separado, com sua própria análise/emparelhamento de aspas, independente de elementos sintáticos fora dos parênteses. Admito que, se você não está procurando esse significado, é muito difícil de interpretar.


Mas sua pergunta, tal como está escrita, não faz sentido. A coisa toda depende do(s) significado(s) muito especial(is) da $casca. Se mudássemos isso para algum outro símbolo monetário,

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

então seria tratado como duas palavras:

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

porque, se um caractere não em branco e não especial aparecer imediatamente antes de uma aspa de abertura ou imediatamente após uma aspa de fechamento, ele será incluído na mesma string que os caracteres entre aspas. Por exemplo,

    cat Wal"*"mart

procura um arquivo chamado Wal*mart, não um arquivo chamado Wal, um chamado *e um chamado mart- Wal"*"marté equivalente a Wal\*marte "Wal*mart". Da mesma forma, o exemplo a seguir mostra quatro palavras:

    um" "duas fivelas" meu "sapato /não/seja/a/" "/cadete sqrt"(2)"
    ↑-------↑ ↑-------------↑ ↑-----------------------↑ ↑-- -----↑

Não sei de onde você tirou o detalhamento de três linhas que mostrou em sua pergunta.

informação relacionada