Comment échapper correctement aux points d'exclamation en bash?

11

Aujourd'hui, j'ai été pris en flagrant délit en tentant de coder au golf un générateur de mot de passe pour Twitter.

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

90 caractères. Comme il s'agit de beaucoup d'espace libre, j'ai décidé de relever la barre et de le rendre exécutable aussi.

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 caractères. Sympa, sauf visiblement bash étouffe sur le point d'exclamation.

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

Point d'exclamation pesky. "Fuyons-y," pensai-je! J'ai un personnage de rechange après tout.

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

Évidemment...

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

Laissant mon code asinine jouer au golf - je ne peux pas l'expliquer.

Avec \!, le point d'exclamation a été échappé, sauf qu'il ne l'était vraiment pas, car il a \!été laissé tel quel echopour reprendre.

Une solution aurait pu être utilisée à la \x21place, mais je ne suis pas convaincu que ce soit la bonne façon d'échapper à un point d'exclamation dans une commande bash.

tl; dr: Comment échapper correctement un point d'exclamation dans une commande bash?

badp
la source
Quelqu'un utilise- t-il réellement la !eventsyntaxe en premier lieu? Cela ne m'a toujours causé que des ennuis.
badp
Je l'utilise presque quotidiennement (pour la plupart des 20 dernières années) !:0 !$et !^économise tellement de temps et de frappe.
Alexx Roche

Réponses:

7

Utilisez des guillemets 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

Les règles de !ont été en quelque sorte greffées par la suite sur les autres règles de citation (de csh). Ils étaient très utiles lorsque les shells n'avaient pas d'édition en ligne de commande, mais certaines personnes les utilisent encore maintenant.

PS Puisque vous codez pour 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

Cela fonctionne sur la plupart des unités:

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

(Je ne comprends pas pourquoi vous voulez créer un script ou pourquoi le nom du script doit être composé de deux lettres.)

Gilles 'SO- arrête d'être méchant'
la source
Je ne savais pas $''. :) PS: C'était pour essayer d'utiliser ces personnages de rechange. J'ai un sentiment de gaspillage lorsque je poste des tweets de moins de 140 caractères.
badp
@badp: Essayez donc de lui faire générer des mots de passe mémorables . (Comme dans pwgenvs. pwgen -s)
Gilles 'SO- arrête d'être méchant'
Pourrait aussi bien utiliser dadadodo pour des phrases de passe mémorables mais absurdes alors :)
badp
1

J'aurais dû googler avant de demander.

Comme vous ne dépendez pas de bash pour développer les variables [..], vous pouvez utiliser des guillemets simples à la place. Les chaînes entre guillemets simples ne sont pas développées par bash.

honk en réponse à Comment puis-je échapper à un point d'exclamation?

badp
la source
1
Je ne marque pas cette réponse comme acceptée, car elle ne répond qu'à ce cas spécifique. En règle générale, vous ne pouvez pas vous en tirer sans expansion.
badp