如何在bash中正确转义感叹号?

bad*_*adp 12 bash command-history quoting

今天,我在尝试为 Twitter 编写密码生成器的代码时被当场抓获。

import string as s,random;print ''.join(random.sample(s.letters+s.digits+s.punctuation,9))
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

139 个字符。很好,除了很明显 bash 窒息在感叹号上。

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
Run Code Online (Sandbox Code Playgroud)

讨厌的感叹号。“让我们逃离它,”我想!毕竟我有一个备用角色。

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
Run Code Online (Sandbox Code Playgroud)

明显地...

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))
Run Code Online (Sandbox Code Playgroud)

把我的 asinine 代码放在一边——我无法解释这一点。

使用\!,感叹号被转义了,但实际上并没有,因为它\!保持原样以供echo拿起。

本来可以使用一种解决方案\x21,但我不相信这是在 bash 命令中转义感叹号的正确方法。

tl; dr:你如何正确地逃避 bash 命令中的感叹号?

Gil*_*il' 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
Run Code Online (Sandbox Code Playgroud)

之后的规则!被移植到其他引用规则上(来自 csh)。当 shell 没有命令行编辑功能时,它们非常有用,但现在有些人仍在使用它们。

PS 由于您正在为 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
Run Code Online (Sandbox Code Playgroud)

这适用于大多数 unice:

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

(不是说我理解您为什么要创建脚本或为什么脚本名称必须是两个字母。)