Hay dos cosas: en Primer lugar, bash reconoce el formato ASCII de comillas dobles, "
(código de carácter 0x22) como una doble cita; no reconoce la fantasía unicode de comillas dobles, "
(unicode U+201 O, la codificación UTF-8 0xe2809d) como otra cosa que una secuencia aleatoria de bytes (o tal vez como un carácter aleatorio, si se utiliza una localización UTF-8). Esto es lo fundamental para lograr: tan lejos como bash se refiere, "
no es una cita, es simplemente algo que sucede a parecerse a una cita cuando se imprime.
La segunda complicación es que el unicode doble cita es un juego de caracteres multibyte, si bash no está en una localización UTF-8 puede tratar algunos de los bytes de manera diferente que los otros(!)
Para ver el efecto de lo primero, trate de sustituir cada ocurrencia de una doble cita con la cadena WIBBLE
- otra secuencia arbitraria que no tiene ningún significado especial para el shell:
$ echo "The path to my home directory is: $HOME bar"
The path to my home directory is: /Users/gordon bar
$ echo "The path to my home directory is: $HOME bar"
"The path to my home directory is: /Users/gordon bar"
$ echo WIBBLEThe path to my home directory is: $HOME barWIBBLE
WIBBLEThe path to my home directory is: /Users/gordon barWIBBLE
En el primer comando (con ASCII dobles comillas), las comillas se analiza y se retira por bash antes de que el argumento(s) se pasan a la echo
comando, y por lo tanto no se imprimen. En la segunda y la tercera (con lujo de comillas dobles y WIBBLE en lugar de la llanura comillas), son tratadas como parte de las cadenas que se pasan a echo
, lo echo
imprime como parte de su salida.
$ echo "The path to my home directory is: $HOME (foo) bar"
The path to my home directory is: /Users/gordon (foo) bar
$ echo "The path to my home directory is: $HOME (foo) bar"
-bash: syntax error near unexpected token `('
$ echo WIBBLEThe path to my home directory is: $HOME (foo) barWIBBLE
-bash: syntax error near unexpected token `('
En el segundo y tercer comandos (con lujo de comillas dobles y WIBBLE), bash ve paréntesis en una no-parte citada del comando (recuerda: tan lejos como bash es de que se trate, de lujo citas son , en realidad, no cita), en un lugar donde no están permitidos por la cáscara de la sintaxis, y por lo tanto se queja.
$ echo "The path to my home directory is: $HOME"
"The path to my home directory is: ??
$ echo WIBBLEThe path to my home directory is: $HOMEWIBBLE
WIBBLEThe path to my home directory is:
Aquí, algo más raro está sucediendo. En el segundo comando, que está buscando un nombre de variable HOMEWIBBLE
, al no encontrarlo, así que reemplazarlo con blanco. En el caso de la primera, con la fantasía de comillas dobles, a mí me parece que es tratar a cada byte de la codificación UTF-8 de "
como un carácter independiente, el tratamiento de la primera como parte del nombre de la variable (causando de nuevo que la variable no se encuentra), y luego simplemente pasando el segundo y tercer bytes a través de, dando un inválido de caracteres UTF-8, que se imprime como ??
. El uso de un volcado hexadecimal para obtener una mejor idea de lo que está pasando le da a este:
$ echo "$HOME"
"??
$ echo "$HOME" | xxd -g1
00000000: e2 80 9d 80 9d 0a ......
Tenga en cuenta que la primera "
pasa a través de la fina, y se muestra en el volcado hexadecimal como e2 80 9d
(la espera codificado en UTF-8 de lujo de doble comilla), pero después de que es sólo 80 9d
-- el primer e2
de la segunda cita de lujo se los comió de alguna manera! (Por CIERTO, el 0a
al final es un salto de línea, marcando el final de la salida.) Para ver lo que está sucediendo, permítanme definir una variable de shell como HOME
+el primer byte de la codificación de la "
, y ver lo que sucede:
$ eval $'HOME\xe2=foo'
$ echo "$HOME"
"foo??
$ echo "$HOME" | xxd -g1
00000000: e2 80 9d 66 6f 6f 80 9d 0a ...foo...
...Así que no hay de qué va: se trata del primer byte de la doble cita de la codificación como parte del nombre de la variable, sustituyendo (si está definido) y, a continuación, pasa a través de los huérfanos de segundo y tercer bytes, dejando inválido UTF-8. No estoy seguro de si esto es un bash bug, la rareza de su análisis, o qué.
De todos modos, los detalles son bastante desordenado, pero la conclusión debe ser claro: no utilizar la fantasía cita en sus scripts de shell; que no funcionan bien.