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

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

今天,我在尝试为 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 个字符。很好,除了 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

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

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 命令中转义感叹号的正确方法。

长话短说:如何正确转义 bash 命令中的感叹号?

答案1

使用单引号:

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

这适用于大多数 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

(我不明白为什么你想创建一个脚本或者为什么脚本名称必须是两个字母。)

答案2

我应该在问之前先用谷歌搜索一下。

由于您不依赖 bash 来扩展变量 [..],因此您可以使用单引号。单引号中的字符串不会被 bash 扩展。

鸣喇叭回复如何避开感叹号?

相关内容