Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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/python\nimport 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.

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

Pesky exclamation point. "Let's escape it," I thought! I do have one spare character after all.

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

Obviously...

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

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?

share|improve this question
    
Does anyone actually use the !event syntax in the first place? It's always caused me only trouble. –  badp Dec 18 '10 at 0:12

3 Answers 3

up vote 6 down vote accepted

Use single quotes:

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

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/python\nimport 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.)

share|improve this answer
    
Didn't know about $''. :) PS: It was to try and use up those spare characters. I have a feeling of waste when I post tweets shorter than 140 characters. –  badp Dec 18 '10 at 0:45
    
@badp: So try to make it generate memorable passwords. (As in pwgen vs. pwgen -s.) –  Gilles Dec 18 '10 at 0:47
    
Might as well use dadadodo for memorable but nonsensical passphrases then :) –  badp Dec 18 '10 at 0:50

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?

share|improve this answer
1  
I'm not marking this answer as accepted, though, because it answers only this specific case. Generally, you can't get away with no expansion. –  badp Dec 18 '10 at 0:26
% python <<'PG'
> import string as s,random
> print"".join(random.sample(s.letters+s.digits+s.punctuation,9))
> PG
<desired output>

Well, that's basically what Gilles has already said, if a little simpler still. But what about the !?

% echo <<'!'
> What 'about' \\\\\\\ it!?!?!!
> !
What 'about' \\\\\\\ it!?!?!!
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.