Se eu digitar isso:
echo "Hello, World!"
ele exibe um prompt de continuação ( PS2
), semelhante a digitar echo \
e pressionar Enter.
Por que isso acontece? Eu sei que !
é uma variável especial que você pode usar para referenciar seu histórico. No entanto, em vez disso, eu digito
echo "Hello, World"!
Eu obtenho minha saída desejada.
O que está acontecendo e por que você não pode usar !
dentro ""
?
!
não é uma _variável especial. (Existe uma variável chamada!
, que você pode acessar com$!
, mas não está relacionada.) É um caractere com um significado especial, dependendo de onde o bash o vê e do que vem depois.O
!
personagem inicia a expansão da história . O Bash executa a expansão do histórico muito cedo ao analisar uma linha de comando, quando está lendo comandos interativamente (não quando está executando um script, mesmo um script originado com.
ousource
de uma linha de comando interativa). Você pode definir a variávelhistchars
para selecionar um caractere diferente em vez de!
(mas a maioria dos outros caracteres ASCII entraria em conflito com o uso comum).O personagem
!
inicia uma substituição de históriaEntão, coisas como
echo "Hello, world"!
ouif ! grep -q foo myfile; …
não acionam nenhuma expansão do histórico.Além disso, as aspas simples e as aspas simples protegem da expansão do histórico (ou seja, o caractere de expansão do histórico não tem seu significado especial quando está dentro de
'…'
), e uma barra invertida que está entre aspas protege esse caractere de iniciar uma expansão do histórico, mas aspas duplas não, exceto ( desde o bash 4.4 ) quando o bash é invocado no modo de compatibilidade POSIX. Ou seja, por padrão,faz
!foo
uma referência histórica que é substituída dentro das aspas duplas. Você não pode simplesmente incluir um ponto de exclamação real em uma string entre aspas duplas, porqueecho "\!foo"
incluiria a barra invertida. Você tem que usar algo comoecho \!"foo"
ouecho '!foo'
. Não sei por que o bash faz isso: é uma decisão de design tomada na década de 1980. (O Bash herda a expansão do histórico do csh, onde é ainda pior: mesmo as aspas simples não protegem da expansão do histórico.)Não consigo reproduzir este caso exato:
Mas pode depender da versão ou configuração do bash. As aspas em si não inibem a expansão do histórico: é o fato de
!"
não se encaixar em nenhuma das formas de designadores de evento .Supondo que você esteja usando
bash
como marcado, use aspas simples em vez de duplasEu acho que é mais provável que você esteja usando
zsh
, e a mesma correção se aplica:Veja Qual é a diferença entre as aspas "...", '...', $'...' e $"..." no shell? para obter mais informações sobre os diferentes tipos de cotações e quando (não) usá-las.