I want to do something like
bzr commit -m "It works!". I can sort of escape the exclamation mark by doing
bzr commit -m "It works\!". However, then my commit message includes the backslash. How do I escape the exclamation mark, while still ignoring the backslash?
Here is another method if you want double quotes as well as the exclamation:
echo "It's broken"'!'
This works even if the
! is not at the end of the line.
echo "hello there"'!'" and goodbye"
Bonus: A similar technique can be used to escape any text in Sh or Bash (with the help of sed): see the first option in this answer. Further, if you have
bash-completion installed, you likely have the
quote() function available already.
Turn off history expansion:
set +o histexpand
You can add one of those commands to your
~/.bashrc if you usually don't use history expansion.
Bash 4.3 added a special case:
the history expansion character is also treated as quoted if it immediately precedes the closing double quote in a double-quoted string
I just now found another way, that will at least work with
echoing strings (sentences) you want to punctuate with an exclamation point. It does an end-run, more or less, around Bash histexpand and takes only a bit longer to code.
The hex for an exclamation point, as listed on
http://www.ascii-code.com/, is 21, so if you put
\x21 at the end of your string,
echo -e $foo, make
$foo its own expanded echo [ie,
foo=$(echo -e "$foo")], what you get when you
echo $foo again is the string with an
! at the end. And no switching histexpand either.
Works for sure in Bash 4+. Earlier versions, ymmv.
I found another way to do this, recently.
This is a general way to get Bash to do escaping for you, so it's handy for arbitrary cases.
From this article:
Enter a line of Bash starting with a # comment, then run !:q on the next line to see > what that would be with proper Bash escaping applied.
bash-3.2$ # This string 'has single' "and double" quotes and a $ bash-3.2$ !:q '# This string '\''has single'\'' "and double" quotes and a $' bash: # This string 'has single' "and double" quotes and a $: command not found
You can also add the
p modifier (so:
!:q:p to avoid the 'command not found' error)