Як правильно уникнути знаків оклику в баші?


11

Сьогодні мене спіймали червоношкірі під час спроби кодування гольфу генератора паролів для Twitter.

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

90 символів. Оскільки це багато вільного місця, я вирішив підняти планку і зробити її також виконуваною.

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 символів. Приємно, за винятком очевидно, що задихається на знак оклику.

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

Песичний знак оклику. "Давайте втечемо від цього", подумав я! Зрештою, у мене є один запасний персонаж.

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

Очевидно ...

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

Залишаючи свій код асінінового гольфу вбік - я не можу цього пояснити.

З \!, знак оклику уникнув, за винятком того, що насправді цього не було, тому що \!залишено так, як echoтреба, щоб забрати.

Одне рішення могло використовуватись \x21натомість, але я не переконаний, що це правильний спосіб уникнути знака оклику в команді bash.

tl; dr: Як правильно уникнути знака оклику в команді bash?


Хтось насправді!event в першу чергу використовує синтаксис? Це завжди заподіювало мені лише неприємності.
badp

Я використовую його майже щодня (протягом більшої частини останніх 20 років.) !:0 !$І !^заощаджую стільки часу і набираючи текст.
Алекс Рош

Відповіді:


7

Використовуйте одинарні лапки:

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

Правила для цього !були сортовані на інші правила цитування згодом (з csh). Вони були дуже корисні ще тоді, коли в оболонках не було редагування командного рядка, але деякі люди все ще використовують їх.

PS Оскільки ви кодуєте баш:

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

Це працює на більшості уніцій:

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

(Не те, щоб я розумів, чому ви хочете створити сценарій або чому ім'я сценарію має бути двома літерами.)


Не знав про $''. :) PS: Це було спробувати використовувати ці запасні символи. У мене виникає почуття марності, коли я публікую твіти, менші за 140 символів.
badp

@badp: Тому спробуйте змусити генерувати пам'ятні паролі. (Як у pwgenпорівнянні pwgen -s.)
Жил "SO- перестань бути злим"

Можна також використовувати dadadodo для пам’ятних, але безглуздих
паролів

1

Я повинен був гугл, перш ніж запитати.

Оскільки ви не залежите від bash для розширення змінних [..], ви можете замість цього використовувати окремі лапки. Рядки в одинарних лапках не розширюються bash.

honk у відповідь на те, як я уникаю знака оклику?


1
Я не відзначаю цю відповідь прийнятою, тому що вона відповідає лише на цей конкретний випадок. Як правило, ви не можете піти без розширення.
badp
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.