Citas de Bash sin escape sobre la sustitución de comandos

Citas de Bash sin escape sobre la sustitución de comandos

¿Alguien puede explicarme por qué esto funciona (enumerando el contenido de un directorio que tiene un espacio en blanco en su nombre):

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

¿No debería interpretarse más bien como:

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

Como por ejemplo con:

ls "my" "dir"

y

ls "my dir"

Respuesta1

La mejor suposición hasta ahora parece ser que estás preguntando:

El comando

    ret="$(ls "mi directorio")"

es un ejemplo bastante terrible de un comando que contiene cuatro comillas dobles ( "). Uno podría esperar ingenuamente que la segunda cita coincida con la primera, y la cuarta coincida con la tercera, así:

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

como ocurre, por ejemplo, con

    eat "afternoon snack" dinner "midnight snack"

En cambio, “funciona” de la siguiente manera:

    ret="$(ls "mi directorio")"
        ↑ ↑------ ↑ ↑
        ↑-------------- ↑

¿Por qué las comillas anidadas se analizan de esa manera?

Este párrafo defiesta(1) puede explicarlo:

Sustitución de comando

                        ⋮
    … Cuando se utiliza el formulario, todos los caracteres entre paréntesis forman el comando….$(command)

Supongo que esto significa lo que ha observado, es decir, el texto entre $(y )se trata como si fuera un comando separado, con su propio análisis/emparejamiento de comillas, independiente de los elementos sintácticos fuera de los paréntesis. Admito que, si no buscas ese significado, es muy difícil de interpretar.


Pero su pregunta, tal como está escrita, no tiene sentido. Todo depende del significado muy especial de $to the shell. Si cambiáramos eso por algún otro símbolo de moneda,

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

entonces sería tratado como dos palabras:

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

porque, si aparece un carácter que no sea un espacio en blanco ni especial inmediatamente antes de una comilla de apertura o inmediatamente después de una comilla de cierre, se incluye en la misma cadena que los caracteres encerrados entre las comillas. Por ejemplo,

    cat Wal"*"mart

busca un archivo llamado Wal*mart, no un archivo llamado Wal, uno llamado *y otro llamado mart- Wal"*"martes equivalente a Wal\*marty "Wal*mart". De manera similar, el siguiente ejemplo muestra cuatro palabras:

    uno" "dos hebillas" mi "zapato /don\'t/be/a/" "/cadet sqrt"(2)"
    ↑------- ↑ ↑-------------- ↑ ↑-------------------- ↑ ↑-- ----- ↑

No sé de dónde sacaste el desglose de tres líneas que mostraste en tu pregunta.

información relacionada