Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

If anyone wants to close as dupe of Differences between doublequotes " ", singlequotes ' ' and backticks ´ ´ on commandline? please leave a comment explaining how answers there explain what I'm asking here. Thanks.

Please look at these commands:

$ notify-send SYNC TIME!
$ notify-send 'SYNC TIME!'
$ notify-send "SYNC TIME!"
bash: !": event not found
$

The first two commands produce a notification bubble as expected. The third gives the error shown.

and

$ echo SYNC TIME!
SYNC TIME!
$ echo 'SYNC TIME!'
SYNC TIME!
$ echo "SYNC TIME!"
bash: !": event not found
$

Here as well, the echo works for first two commands but not in the third.

More problems here (although I was not planning on using this): both notify-send "SYNC!TIME" and echo "SYNC!TIME" give bash: !TIME": event not found.

But both notify-send and echo work with "SYNC! TIME"

Can someone please explain why the bash: !": event not found error appears?

share|improve this question

2 Answers 2

up vote 19 down vote accepted

! is the default history expansion character in Bash, see the section "HISTORY EXPANSION" in the Bash manpage

  • History expansion doesn't take place if the ! is enclosed by single quotes, as in

    notify-send 'SYNC TIME!'
    
  • History expansion doesn't take place if the ! is followed by a space, tab, newline, carriage return, or =, as in

    notify-send SYNC TIME!
    
  • History expansion does take place in

    echo "SYNC TIME!"
    

    So you'll get an error if there isn't a command starting with " in your history

share|improve this answer
2  
This misbehavior can be fixed by adding to your .bashrc the line set +H. Note that ! is already non-special in scripting; treating it as special would break many standards-conforming scripts. It's only treated as "special" in interactive shells, and only by default until you fix it. :-) –  R.. Mar 16 at 17:02

Because in bash, ! is a reserved word (OK, character), it has special meaning in different contexts. In this particular case, you are falling afoul of it's significance in history searching. From man bash:

   History expansions introduce words from the history list into the input
   stream, making it easy to repeat commands, insert the  arguments  to  a
   previous command into the current input line, or fix errors in previous
   commands quickly.

  [...]

   History expansions are introduced by
   the appearance of the  history  expansion  character,  which  is  !  by
   default.   Only  backslash  (\) and single quotes can quote the history
   expansion character.

Basically, what this means is that bash will take the characters after the ! and search your history for the first command it finds that starts with those characters. It is easier to demonstrate than explain:

$ echo foo
foo
$ !e
echo foo
foo

The ! activated history expansion, which matched the first command starting with e which was the previously run echo foo which was then run again. So, when you wrote "SYNC TIME!", bash saw the !", searched history for a command starting with ", failed and complained about it. You can get the same error by running, for example !nocommandstartswiththis.

To print an exclamation mark, you need to escape it in one of these two ways:

echo 'Hello world!'
echo Hello world\!
share|improve this answer
5  
echo Hello world! does work --- history expansion is not triggered by blanks ;-) (ah, the nice corner cases...) –  Rmano Mar 16 at 3:43
    
It's better to rely on escaping the exclamation mark than blanks, though. –  Ehtesh Choudhury Mar 16 at 12:07
    
@Rmano I prefer to explicitly say so rather than guide me of a behavior that it's possible to change –  Braiam Mar 16 at 13:23

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.