Wie entkomme ich Ausrufezeichen in Bash richtig?

11

Heute wurde ich beim Versuch, einen Passwortgenerator für Twitter zu codieren, auf frischer Tat ertappt.

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

90 Zeichen. Da dies viel Platz ist, habe ich beschlossen, die Messlatte höher zu legen und sie auch ausführbar zu machen.

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 Zeichen. Schön, außer offensichtlich Bash Chokes am Ausrufezeichen.

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

Lästiges Ausrufezeichen. "Lass uns entkommen", dachte ich! Ich habe doch einen freien Charakter.

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

Offensichtlich...

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

Lassen Sie meinen Asinine-Code beim Golfen beiseite - das kann ich nicht erklären.

Mit \!wurde das Ausrufezeichen maskiert, außer es war wirklich nicht so, weil das \!so gelassen wurde, wie es ist echo, um es aufzunehmen.

Eine Lösung hätte \x21stattdessen verwendet werden können, aber ich bin nicht davon überzeugt, dass dies der richtige Weg ist, um einem Ausrufezeichen in einem Bash-Befehl zu entkommen.

tl; dr: Wie entgeht man einem Ausrufezeichen in einem Bash-Befehl richtig?

badp
quelle
Hat jemand tatsächlich die Verwendung !eventSyntax in erster Linie? Es hat mir immer nur Ärger gemacht.
Badp

Antworten:

7

Verwenden Sie einfache Anführungszeichen:

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

Die Regeln für !wurden später auf die anderen Zitierregeln übertragen (von csh). Sie waren damals sehr nützlich, als Shells keine Befehlszeilenbearbeitung hatten, aber einige Leute verwenden sie jetzt noch.

PS Da Sie für Bash codieren:

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

Dies funktioniert bei den meisten 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

(Nicht, dass ich verstehe, warum Sie ein Skript erstellen möchten oder warum der Skriptname aus zwei Buchstaben bestehen muss.)

Gilles 'SO - hör auf böse zu sein'
quelle
Wusste nichts davon $''. :) PS: Es war zu versuchen, diese Ersatzcharaktere zu verbrauchen. Ich habe ein Gefühl der Verschwendung, wenn ich Tweets mit weniger als 140 Zeichen poste.
Badp
@badp: Versuchen Sie also, unvergessliche Passwörter zu generieren . (Wie in pwgenvs. pwgen -s)
Gilles 'SO - hör auf böse zu sein'
Könnte dann auch Dadadodo für unvergessliche, aber unsinnige Passphrasen verwenden :)
Badp
1

Ich hätte googeln sollen, bevor ich gefragt habe.

Da Sie zum Erweitern von Variablen [..] nicht auf bash angewiesen sind, können Sie stattdessen einfache Anführungszeichen verwenden. Zeichenfolgen in einfachen Anführungszeichen werden nicht durch Bash erweitert.

Hupen als Antwort auf Wie entkomme ich einem Ausrufezeichen?

badp
quelle
1
Ich markiere diese Antwort jedoch nicht als akzeptiert, da sie nur diesen speziellen Fall beantwortet. Im Allgemeinen kommt man ohne Erweiterung nicht davon.
Badp