Come sfuggire correttamente ai punti esclamativi in ​​bash?


11

Oggi sono stato colto in flagrante mentre tentavo di codificare golf un generatore di password per Twitter.

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

90 caratteri. Dato che c'è molto spazio libero, ho deciso di alzare il livello e renderlo anche eseguibile.

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 caratteri. Bello, tranne ovviamente che soffoca sul punto esclamativo.

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

Punto esclamativo fastidioso. "Scappiamo," ho pensato! Dopotutto, ho un personaggio in più.

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

Ovviamente...

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))

Lasciando da parte il mio codice di golf, non posso spiegarlo.

Con \!, il punto esclamativo è stato evitato, tranne che in realtà non lo era, perché è \!stato lasciato così com'è per echoraccogliere.

\x21Invece, avrebbe potuto utilizzare una soluzione , ma non sono convinto che sia il modo corretto di sfuggire a un punto esclamativo in un comando bash.

tl; dr: Come si evita correttamente un punto esclamativo in un comando bash?


Qualcuno usa effettivamente la !eventsintassi in primo luogo? Mi ha sempre causato solo problemi.
badp

Lo uso quasi quotidianamente (per la maggior parte degli ultimi 20 anni) !:0 !$e !^risparmio così tanto tempo e digitando.
Alexx Roche,

Risposte:


7

Usa virgolette singole:

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

Le regole per !furono in qualche modo innestate sulle altre regole di quotazione in seguito (da csh). Erano molto utili quando le shell non avevano la modifica della riga di comando, ma alcune persone le usano ancora adesso.

PS Dato che stai codificando per 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

Funziona con la maggior parte dei computer:

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

(Non che io capisca perché vuoi creare uno script o perché il nome dello script deve essere di due lettere.)


Non lo sapevo $''. :) PS: è stato per provare a usare quei personaggi di riserva. Ho una sensazione di spreco quando inserisco tweet di lunghezza inferiore a 140 caratteri.
badp

@badp: quindi cerca di far sì che generi password memorabili . (Come in pwgenvs pwgen -s..)
Gilles 'SO- smetti di essere malvagio' il

Potrebbe anche usare dadadodo per passphrase memorabili ma senza senso allora :)
badp

1

Avrei dovuto cercare su Google prima di chiedere.

Dato che non si dipende da bash per espandere le variabili [..] è possibile invece utilizzare virgolette singole. Le stringhe tra virgolette singole non sono espanse da bash.

suonare il clacson in risposta a Come posso evitare un punto esclamativo?


1
Non segnerò questa risposta come accettata, però, perché risponde solo a questo caso specifico. In generale, non puoi cavartela senza espansione.
badp
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.