Como escapar corretamente de pontos de exclamação no bash?

11

Hoje, fui flagrado ao tentar codificar um gerador de senhas para o Twitter no Twitter.

import string as s,random;print ''.join(random.sample(s.letters+s.digits+s.punctuation,9))

90 caracteres. Como isso é muito espaço livre, decidi aumentar a barra e torná-la executável também.

echo -e "#!/usr/bin/python\nimport string as s,random;print ''.join(random.sample(s.letters+s.digits+s.punctuation,9))">pg;chmod +x pg;./pg

139 caracteres. Bom, exceto que obviamente a pancada sufoca o ponto de exclamação.

badp@delta:~$ echo -e "#!/usr/bin/python\nimport string as s,random;print ''.join(random.sample(s.letters+s.digits+s.punctuation,9))">pg;chmod +x pg;./pg
bash: !/usr/bin/python\nimport: event not found

Ponto de exclamação rouco. "Vamos escapar", pensei! Eu tenho um caractere reserva, afinal.

echo -e "#\!/usr/bin/python\nimport string as s,random;print ''.join(random.sample(s.letters+s.digits+s.punctuation,9))">pg;chmod +x pg;./pg

Obviamente ...

badp@delta:~$ echo -e "#\!/usr/bin/python\nimport string as s,random;print ''.join(random.sample(s.letters+s.digits+s.punctuation,9))">pg;chmod +x pg;./pg
./pg: line 2: syntax error near unexpected token '('
./pg: line 2: 'import string as s,random;print ''.join(random.sample(s.letters+s.digits+s.punctuation,9))'
badp@delta:~$ cat pg
#\!/usr/bin/python
import string as s,random;print ''.join(random.sample(s.letters+s.digits+s.punctuation,9))

Deixando meu asinino código de golfe de lado - não posso explicar isso.

Com \! , o ponto de exclamação foi escapado, exceto que realmente não foi, porque o \! foi deixado como está para echo para pegar.

Uma solução poderia estar usando \x21 , mas não estou convencido de que essa seja a maneira correta de escapar de um ponto de exclamação em um comando bash.

tl; dr: Como você escapa de um ponto de exclamação em um comando bash?

    
por badp 18.12.2010 / 01:10

2 respostas

7

Use aspas simples:

echo -e '#!/usr/bin/python\nimport string as s,random;print "".join(random.sample(s.letters+s.digits+s.punctuation,9))'>pg;chmod +x pg;./pg

As regras para ! foram posteriormente enxertadas nas outras regras de cotação (do csh). Eles eram muito úteis quando os shells não tinham edição de linha de comando, mas algumas pessoas ainda os usam agora.

P.S. Já que você está codificando para o bash:

echo $'#!/usr/bin/python\nimport string as s,random;print"".join(random.sample(s.letters+s.digits+s.punctuation,9))'>pg;chmod +x pg;./pg

Isso funciona na maioria dos unices:

echo python -c \''import string as s,random;print"".join(random.sample(s.letters+s.digits+s.punctuation,9))'\'>pg;chmod +x pg;./pg

(Não que eu entenda porque você quer criar um script ou porque o nome do script tem que ser duas letras.)

    
por 18.12.2010 / 01:28
1

Eu deveria ter pesquisado no Google antes de perguntar.

Since you do not depend on bash to expand variables [..] you could use single quotes instead. Strings in single quotes are not expanded by bash.

honk in reply to How do I escape an exclamation mark?

    
por 18.12.2010 / 01:25