Há duas coisas acontecendo aqui: Primeiro, o bash reconhece as aspas simples ASCII simples "
(código de caractere 0x22) como aspas duplas; ele não reconhece as aspas duplas à esquerda do unicode chique “
(unicode U + 201C, UTF-8 que codifica 0xe2809c) e a citação dupla à direita correspondente ”
(unicode U + 201D, UTF-8 que codifica 0xe2809d) como algo diferente de seqüências aleatórias de bytes (ou talvez caracteres aleatórios, se estiver usando um código de idioma UTF-8). É isso que você deve perceber: no que diz respeito ao bash, “
e ”
na verdade não são aspas , são apenas coisas que parecem aspas quando são impressas.
A segunda complicação é que as aspas duplas unicode são caracteres multibyte; portanto, se o bash não estiver em um código de idioma UTF-8, ele poderá tratar alguns bytes de maneira diferente dos outros (!)
Para ver o efeito da primeira coisa, tente substituir cada ocorrência de aspas duplas pela string WIBBLE
- outra sequência arbitrária que não tem significado especial para o 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
No primeiro comando (com aspas duplas ASCII), as aspas são analisadas e removidas pelo bash antes que os argumentos sejam passados para o echo
comando e, portanto, não são impressos. Na segunda e na terceira (com aspas duplas sofisticadas e WIBBLE no lugar de aspas simples), elas são tratadas apenas como parte das strings a serem passadas echo
, e as echo
imprimem como parte de sua saída.
$ 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 `('
Nos segundo e terceiro comandos (com aspas duplas e WIBBLE), o bash vê parênteses em uma parte não citada do comando (lembre-se: no que diz respeito ao bash, aspas extravagantes não são realmente aspas ), em um local onde eles não são permitidos pela sintaxe do shell e, portanto, reclama.
$ 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:
Aqui, algo mais estranho está acontecendo. No segundo comando, ele está procurando uma variável denominada HOMEWIBBLE
, não a encontra, substituindo-a por uma em branco. No caso do primeiro, com aspas duplas, parece-me tratar cada byte da codificação UTF-8 ”
como um caractere separado, tratando o primeiro como parte do nome da variável (causando novamente a variável não encontrado) e, em seguida, basta passar o segundo e o terceiro bytes, fornecendo um caractere UTF-8 inválido, que é impresso como ??
. Usar um dump hexadecimal para ter uma idéia melhor do que está acontecendo fornece:
$ echo “$HOME”
“??
$ echo “$HOME” | xxd -g1
00000000: e2 80 9c 80 9d 0a ......
Observe que a primeira “
passa bem e aparece no dump hexadecimal como e2 80 9c
(a cotação dupla extravagante codificada UTF-8 esperada), mas depois disso é apenas 80 9d
- a primeira e2
da segunda cotação extravagante foi comida de alguma forma! (BTW, o 0a
no final é um avanço de linha, marcando o final da saída.) Para ver o que está acontecendo, deixe-me definir uma variável do shell como HOME
+ o primeiro byte da codificação ”
e observe o que acontece:
$ eval $'HOME\xe2=foo'
$ echo “$HOME”
“foo??
$ echo “$HOME” | xxd -g1
00000000: e2 80 9c 66 6f 6f 80 9d 0a ...foo...
... Então, o que está acontecendo: trata o primeiro byte da codificação de aspas duplas como parte do nome da variável, substitui-o (se definido) e passa apenas pelo segundo e terceiro bytes órfãos, deixando UTF inválido- 8) Não tenho certeza se isso é um bug do bash, estranheza de sua análise ou o quê.
De qualquer forma, os detalhes são bastante confusos, mas a explicação deve ser clara: não use aspas sofisticadas em seus scripts de shell; eles não vão funcionar direito. E o mesmo se aplica a aspas simples e outros sinais de pontuação unicode.
'
e ou"
conforme apropriado, quando aplicável. Eu também sugiro fortemente que você nunca use o TextEdit e, em vez disso, use um editor de código apropriado, por exemplo, Sublime Text.