3 votos

¿Lo que hace que la utilidad del intérprete bash interpretar diferentemente estándar e inteligentes entre comillas dobles, en un script de shell, creado en TextEdit?

Mientras que el aprendizaje de bash scripting por ir a través de una Guía del Principiante, he tratado de escribir algunas líneas de código en la .sh archivo, creado en TextEdit en mac os Yosemite y ejecutarlo con el comando bash \path\to\script\file\example_script.sh en bash Terminal.

La línea de código que he probado:

echo "The path to my home directory is: $HOME"

La salida estándar (stdout) en la Terminal:

"The path to my home directory is: ??

en lugar de llegar:

The path to my home directory is: /Users/Ri$hi

Entonces, llegué a saber sobre el curioso caso de "smart quotes" de un stackexchange, y jugó con algunos divertidos combos, como a continuación:

La línea de código que he probado más tarde:

Escenario 1:

echo "The path to my home directory is: $HOME (foo) bar"

stdout:

-bash: syntax error near unexpected token `('

Escenario 2:

echo "The path to my home directory is: $HOME (foo) bar"

stdout:

The path to my home directory is: /Users/Ri$hi (foo) bar

Escenario 3:

echo "The path to my home directory is: $HOME" "(foo)" "bar"

stdout:

-bash: syntax error near unexpected token `('

Escenario 4:

echo "The path to my home directory is: $HOME" "(foo)" "bar"

stdout:

-bash: syntax error near unexpected token `('

Escenario 5:

echo "The path to my home directory is: $HOME" "(foo)" "bar"

stdout:

"The path to my home directory is: ?? (foo) "bar"

Así que pensé, ¿por qué no averiguar la razón de forma interactiva en este foro.

NOTA: el Terminal siempre muestra doble estándar citar " cuando Shift+" es presionado, pero permite la visualización de smart comillas " "a través de +C, +V operación.

9voto

Nate Puntos 220

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.

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X