How to properly escape exclamation points in bash?

Today, I was caught redhanded while attempting to code golf a password generator for Twitter.

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

90 chars. Since that is a lot of spare space, I decided to raise the bar and make it executable too.

echo -e "#!/usr/bin/pythonnimport string as s,random;print ''.join(random.sample(s.letters+s.digits+s.punctuation,9))">pg;chmod +x pg;./pg

139 chars. Nice, except obviously bash chokes on the exclamation point.

<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="86e4e7e2f6c6e2e3eaf2e7">[email protected]</a>:~$ echo -e "#!/usr/bin/pythonnimport string as s,random;print ''.join(random.sample(s.letters+s.digits+s.punctuation,9))">pg;chmod +x pg;./pg
bash: !/usr/bin/pythonnimport: event not found

Pesky exclamation point. “Let’s escape it,” I thought! I do have one spare character after all.

echo -e "#!/usr/bin/pythonnimport string as s,random;print ''.join(random.sample(s.letters+s.digits+s.punctuation,9))">pg;chmod +x pg;./pg

Obviously…

<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c1a3a0a5b181a5a4adb5a0">[email protected]</a>:~$ echo -e "#!/usr/bin/pythonnimport 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))'
<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="284a494c58684c4d445c49">[email protected]</a>:~$ cat pg
#!/usr/bin/python
import string as s,random;print ''.join(random.sample(s.letters+s.digits+s.punctuation,9))

Leaving my asinine code golfing aside — I can’t explain this.

With !, the exclamation point was escaped, except it really wasn’t, because the ! was left as-is for echo to pick up.

One solution could have been using x21 instead, but I’m not convinced that’s the proper way of escaping an exclamation point in a bash command.

tl;dr: How do you properly escape an exclamation point in a bash command?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Use single quotes:

echo -e '#!/usr/bin/pythonnimport string as s,random;print "".join(random.sample(s.letters+s.digits+s.punctuation,9))'>pg;chmod +x pg;./pg

The rules for ! were sort of grafted onto the other quoting rules afterwards (from csh). They were very useful back when shells didn’t have command line editing, but some people still use them now.

P.S. Since you’re coding for bash:

echo $'#!/usr/bin/pythonnimport string as s,random;print"".join(random.sample(s.letters+s.digits+s.punctuation,9))'>pg;chmod +x pg;./pg

This works on most 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

(Not that I understand why you want to create a script or why the script name has to be two letters.)

Method 2

I should have Googled before I asked.

Since you do not depend on bash to expand variables [..] you could use single quotes instead. Strings in single quotes are not expanded by bash.

honk in reply to How do I escape an exclamation mark?


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x