No Zsh 5.9, podemos usar printf
para escapar de uma string:
$ printf '%q' 'One! Two'
One\!\ Two
Isso produz a saída correta de escapar do !
e do espaço. Agora vamos fazer isso como um script:
#!/bin/zsh
printf '%q' "${1}"
Agora, se executarmos, o !
não escapa , mas o espaço é:
$ ./my-script 'One! Two'
One!\ Two
Se eu alterar o script para /bin/bash
(versão 3.2), ele escapará corretamente do !
espaço e.
Isso é um bug do Zsh ou há algum detalhe sutil que estou perdendo?
Parece que ele verifica as configurações atuais do shell para determinar se o estrondo é especial. A expansão do histórico não está habilitada por padrão em shells não interativos, portanto não é especial em um script.
O mesmo parece se aplicar à
${(q)var}
expansão dos parâmetros.Honestamente, acho que é uma escolha um tanto estranha, pois embora signifique que a saída é adequada como entrada para a mesma sessão de shell, geralmente não é adequada como entrada para todas as sessões zsh. Sempre escapar do estrondo não deve causar problemas,
\!
independentemente!
de sebanghist
estiver definido.Você pode usar
${(qq)var}
aspas simples na string (ou${(qqqq)var}
usar$'...'
aspas). O estrondo seria então citado junto com todo o resto. Ou transforme-o em uma função: