¿Qué hace que la utilidad del intérprete bash interprete citas dobles estándar e inteligentes, presentes en un guión de shell, creadas en TextEdit?

Mientras aprendía scripts bash siguiendo una Guía para principiantes , intenté escribir algunas líneas de código en el file .sh , creadas en TextEdit en macOS Yosemite y ejecutándolas con el command bash \path\to\script\file\example_script.sh en Bash Terminal.

Línea de código que probé por primera vez:

 echo “The path to my home directory is: $HOME” 

Salida estándar (stdout) en la Terminal:

 “The path to my home directory is: ?? 

en lugar de get:

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

Luego, llegué a conocer el curioso caso de "smart quotes" de un stackexchange , y jugué con algunos combos divertidos, como a continuación:

Línea de código que probé 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” 

Entonces, pensé por qué no descubrí la razón interactivamente en este foro.

NOTA: El terminal siempre muestra una comilla doble estándar " cuando se pulsa Shift + " , pero permite mostrar comillas dobles inteligentes “ ” través de + C , + V operación.

  • El Capitan, o una edición anterior de TextEdit
  • ¿Es posible cambiar el tamaño de window pnetworkingeterminado de un file .txt en TextEdit?
  • TextEdit se bloquea al intentar volver a abrir documentos. ¿Puedo recuperar todos los documentos excepto el que causa problemas?
  • ¿Es posible salir de TextEdit haciendo clic en la x roja del último file abierto (sin software adicional)?
  • TextEdit muestra dialogs sobre no tener permiso para abrir ningún file
  • Distancia de tabulación de text sin formatting TextEdit
  • Textedit se estrelló y perdió un file previamente guardado
  • ¿Todavía puede establecer un estilo de color de background en Textedit en Mavericks?
  • One Solution collect form web for “¿Qué hace que la utilidad del intérprete bash interprete citas dobles estándar e inteligentes, presentes en un guión de shell, creadas en TextEdit?”

    Aquí están sucediendo dos cosas: Primero, bash reconoce la comilla doble ASCII simple, " (código de carácter 0x22) como una comilla doble, no reconoce la doble comilla izquierda unicode elegante (Unicode U + 201C, Codificación UTF-8 0xe2809c) y la correspondiente comilla doble derecha, (Unicode U + 201D, encoding UTF-8 0xe2809d) como cualquier cosa que no sean secuencias aleatorias de bytes (o tal vez como caracteres aleatorios, si usa una configuration regional UTF-8 ). Esto es algo fundamental que debemos tener en count: en lo que respecta a bash, y realidad no son citas , simplemente son cosas que parecen ser citas cuando se imprimen.

    La segunda complicación es que las comillas dobles Unicode son caracteres multibyte, por lo que si bash no está en una configuration regional UTF-8, puede tratar algunos de los bytes de forma diferente que otros (!)

    Para ver el efecto de la primera cosa, intente replace cada aparición de una comilla doble con la cadena WIBBLE – otra secuencia arbitraria que no tiene un significado especial para la 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 command (con comillas dobles ASCII), las comillas se analizan y eliminan mediante bash antes de que los arguments se pasen al command echo y, por lo tanto, no se impriman. En el segundo y el tercero (con dobles comillas elegantes y WIBBLE en lugar de comillas simples), solo se tratan como parte de las cadenas que se pasarán a echo , por lo que 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 los commands segundo y tercero (con dobles comillas elegantes y WIBBLE), bash ve paréntesis en una parte del command que no está entre comillas (recuerde: en lo que respecta a bash, las citas de fantasía no son realmente citas ), en un lugar donde no están permitidos por la syntax del shell, y por lo tanto se quejan.

     $ 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 extraño está sucediendo. En el segundo command, está buscando una variable llamada HOMEWIBBLE , que no la encuentra, por lo que la reemplaza con un espacio en blanco. En el caso del primero, con las elegantes comillas dobles, me parece que trata cada byte de la encoding UTF-8 de como un carácter separado, tratando el primero como parte del nombre de la variable (causando de nuevo el variable que no se encuentra), y luego simplemente pasar el segundo y tercer bytes, dando un carácter UTF-8 no válido, que se imprime como ?? . Usar un volcado hexadecimal para tener una mejor idea de lo que está pasando le da a esto:

     $ echo “$HOME” “?? $ echo “$HOME” | xxd -g1 00000000: e2 80 9c 80 9d 0a ...... 

    Tenga en count que el primero pasa bien, y aparece en el volcado hexadecimal como e2 80 9c (la doble cita de fantasía codificada UTF-8 esperada), pero después de eso es solo 80 9d – el primer e2 de la segunda cita de fantasía ¡Me lo comieron de alguna manera! (Por cierto, el 0a al final es un salto de línea, marcando el final de la salida). Para ver qué sucede, permítame definir una variable de shell como HOME + el primer byte de la encoding de , y observe lo que sucede:

     $ eval $'HOME\xe2=foo' $ echo “$HOME” “foo?? $ echo “$HOME” | xxd -g1 00000000: e2 80 9c 66 6f 6f 80 9d 0a ...foo... 

    … Así que está sucediendo lo siguiente: es tratar el primer byte de la encoding de comillas dobles como parte del nombre de la variable, sustituyéndolo (si está definido), y luego simplemente pasando por el segundo y tercer bytes huérfanos, dejando un UTF no válido 8. No estoy seguro si esto es un error de bash, rareza de su análisis, o qué.

    De todos modos, los detalles son un poco desorderados, pero la conclusión debe ser clara: no use citas extravagantes en sus scripts de shell; no funcionarán bien Y lo mismo se aplica a las elegantes comillas simples y otros signos de puntuación Unicode.

    Loving Apple Products like poisoning (iPhone, iPad, iMac, Macbook, iWatch).