Here's a little puzzle. I'm trying to enter the string on the following line...
I Didn't Say Anything!
...as an argument to a command. (It's a menu item for a DVD menu). To illustrate the problem, I'll use the echo command.
Code:
$ echo "I Didn't Say Anything!"
bash: !": event not found
I used quotes so that the string gets treated as a single argument, which doesn't matter for 'echo' but does for a DVD menu. I chose double quotes in order to escape the single quote. However, as the Bash Reference Manual says, "Only `\' and `'' may be used to escape the history expansion character". Hence the exclamation mark is treated as an attempt at history expansion, leading to "event not found". OK, so how about single quotes?
Code:
$ echo 'I Didn't Say Anything'
> oops, quote not closed'
I Didnt Say Anything
oops, quote not closed
$ echo 'I Didn\'t Say Anything'
> oops, quote not closed again'
I Didn\t Say Anything
oops, quote not closed again
I can't use single quotes because then I can't escape the quote, not even with a backslash. (The 'oops' lines above are just to illustrate that Bash gave me an unterminated quote prompt on the following line.)
OK, well the Bash Reference Manual says I can use a backslash to escape the exclamation mark, so here goes.
Code:
$ echo "I Didn't Say Anything\!"
I Didn't Say Anything\!
The backslash successfully escapes the exclamation mark, but it doesn't get swallowed up, instead remaining in the resulting string and hence in my DVD menu. Is this a bash bug? I would have thought that when an escape character is operative, it should not appear in the output.
I worked around the problem as follows:
Code:
$ echo I\ Didn\'t\ Say\ Anything\!
I Didn't Say Anything!
I.e. I dispensed with quotes and instead used escaped spaces to keep the string as a single parameter.
So my questions are:
- Is this a Bash bug?
- Is there a more elegant solution? Maybe redefining the history expansion character, but I feel that shouldn't be necessary.