¿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:

  • ¿Qué daemon de correo ejecuta OS X 10.8.4 de manera pnetworkingeterminada?
  • Cómo identificar el tipo de file para una gran cantidad de files y adjuntar la extensión adecuada a cada uno
  • Matar processs automáticamente que superan x% CPU
  • ¿Comando de análisis incorrecto de la página de manual de date?
  • ¿Es posible que algún hacker haya iniciado session en mi computadora?
  • Mavericks SSH teclas y llavero
  •  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.

  • ¿Es posible automatizar FTP en la Terminal?
  • ¿Cómo restauro una versión anterior de mis files de pares de keys ssh?
  • ¿Cómo combino celdas separadas en una spreadsheet Numbers y pego el resultado como text en un documento TextEdit?
  • ¿Cómo agregar un directory a mi ruta que incluya dos puntos y un espacio?
  • Cómo cambiar la versión bash con homebrew
  • ¿Instalando .pkg con terminal?
  • 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).