Citações, expansão variável, curingas e tudo mais mencionado na seção manual do bash expansão é tratada pelo bash.
Por exemplo, quando você executa o comando bash echo "x is: $x"
, o bash analisa isso para descobrir que ele precisa executar o comando echo
com um argumento que é x is: 12345
. Dado echo "x is" "$x"
, bash executa echo
com dois argumentos: x is
e 12345
- é por isso que os dois espaços dentro das aspas são preservados (eles fazem parte do argumento que echo imprime não modificado), mas os dois espaços fora das aspas não são (para o shell, dois espaços para separar argumentos são tão bons quanto um único, e echo
sempre imprime um único espaço entre eles).
O comando echo
(ou qualquer outro comando) não tem como saber qual comando shell produziu o argumento x is: 12345
, ou se um shell estava envolvido. Aqui estão alguns exemplos de comandos que produzem este argumento:
echo "x is: 12345"
echo 'x is: 12345'
echo x\ is:\ 12345
echo "x is: $x"
echo 'x is:'\ "$x"
echo "$(echo "x ")is: $x"
# Assume there is no other file whose name begins with x in the current directory
touch "x is: $x"; echo x*
Ou pode ser exec "echo", "x is: 12345"
em Perl ou execlp("echo", "echo", "x is: 12345")
em C, etc.
Isso vale para todos os comandos. E o mesmo princípio vale para outras conchas, embora cada uma tenha um conjunto de expansões ligeiramente (ou significativamente) diferente.
Por outro lado, opções são manipuladas pelo comando. Por exemplo, ls -l -t
e ls -l "-t"
no bash (ou qualquer shell semelhante) executam ls
exatamente da mesma maneira, com os dois argumentos -l
e -t
. É por isso que nenhuma forma de cotação de shell ajudará você se desejar executar ls
para exibir informações sobre um arquivo chamado -t
. Você pode fazer isso com ls -l -- -t
, ou seja, passando --
como argumento. Esta é uma convenção seguida pela maioria dos comandos: nada depois de --
é analisado como uma opção. Mais uma vez, esta é uma característica do comando; para o shell, um traço principal não é nada especial.
Uma coisa que pode ficar complicada são as barras invertidas. No bash e em outros shells, a barra invertida fora de qualquer citação significa que o próximo caractere perde seu significado especial. Por exemplo, echo \"x\ is:\ 12345\"
imprime "x is: 12345"
, porque cada um dos caracteres precedidos por uma barra invertida perde seu significado especial (sintaxe de cotação para "
, separador de palavras para espaços). Mas alguns comandos também interpretam barras invertidas. Quando isso acontecer, você precisa garantir que a barra invertida chegue até eles. Por exemplo, no bash, o comando echo
imprime barras invertidas literalmente por padrão, mas se você passar a opção -e
ou executar shopt xpg_echo
primeiro, então echo
terá suas próprias seqüências de escape (isso é para bash, o% O comandoecho
em shells diferentes e em sistemas diferentes tem regras diferentes sobre se eles tratam as barras invertidas especialmente). Por exemplo, echo 'a\nb'
imprime a\nb
, enquanto echo -e 'a\nb'
imprime a
-newline- b
porque \n
significa “nova linha” para echo -e
. Por outro lado, echo a\nb
imprime anb
, pois \n
é expandido pelo shell e há \
significa "citar o próximo caractere".
Além disso, tenha cuidado quando vários invólucros estiverem envolvidos, por exemplo, com SSH. Quando você executa ssh
em um shell, o shell local analisa o comando como de costume. O cliente SSH une seus argumentos de não opção com espaços no meio e envia a sequência resultante para o servidor SSH. O servidor SSH passa essa string para o shell remoto. Isso significa que existem duas rodadas completas de expansão de shell entre o que você digita em um terminal ou em um shell script e o que é executado na máquina remota.