Server Fault is a question and answer site for system and network administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Try executing the following under a bash shell echo "Reboot your instance!"

On my installation:

root@domU-12-31-39-04-11-83:/usr/local/bin# bash --version
GNU bash, version 4.1.5(1)-release (i686-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
root@domU-12-31-39-04-11-83:/usr/local/bin# uname -a
Linux domU-12-31-39-04-11-83 2.6.35-22-virtual #35-Ubuntu SMP Sat Oct 16 23:57:40 UTC 2010 i686 GNU/Linux
root@domU-12-31-39-04-11-83:/usr/local/bin# echo "Reboot your instance!"
-bash: !": event not found

Can anyone please explain what is "bash events?" I've never heard this concept before. Also, how should I output "!" at the end of the sentence?

share|improve this question
up vote 42 down vote accepted

! is a special character to bash, it is used to refer to previous commands; eg,

!rm

will recall and execute the last command that began with the string "rm", and

!rm:p

will recall but not execute the last command that began with the string "rm". bash is interpreting the exclamation mark in echo "reboot your instance!" as "substitute here the last command that began with the character(s) immediately following the exclamation mark", and grumbles at you that it cannot find an event (command) in your history that began with a single double-quote.

Try

echo reboot your instance\!

to protect (escape) the exclamation mark from bash.

share|improve this answer
    
Yes, but should happen if I want to use echo -e "some text $ENV_VAL some more text\nReboot now!" ? – Maxim Veksler Dec 2 '10 at 13:25
1  
Write two echo statements; you get the linefeed for free. – MadHatter Dec 2 '10 at 14:22
1  
Simple solution is to use single quotes and double quotes at once: echo -e "Text\nReeboot"'!' – mmey Oct 2 '14 at 4:51
    
I'm not sure that's simpler, but it will work, yes. – MadHatter Oct 2 '14 at 7:04
1  
This sucks. If I don't escape the exclamation mark, bash throws a fit. If I do escape it, the backslash is included in the final string. Why do you do this, Bash!! (pastebin.com/g4PYv56A) – Hubro Jan 23 '15 at 7:46

You can turn off history substitution using set +H.

share|improve this answer
    
Do you know the reasoning behind the syntax? It seems really counter intuitative. You'd think you'd type +H to enable something and -H to disable something. – PunkyGuy May 16 at 9:19
3  
@PunkyGuy: I don't know the history (pun intended) behind it, but Unix options typically start with a hyphen (or minus) and + is simply the opposite of that. – Dennis Williamson May 16 at 13:19

To solve your original problem, try using single quotes, rather than double quotes. With the latter, bash will attempt to expand certain characters before passing the result on to the command (echo in this case). With single quotes, bash passes the entire string, unchanged.

! is used in commands to refer to the command line history. See: http://tldp.org/LDP/abs/html/abs-guide.html#HISTCOMMANDS for a full set. With the above example, bash is trying to expand !" as a reference to an event before echo gets a look in, hence the error.

Note that in scripts, all of the history commands are disabled, as they only make sense in an interactive shell.

The only one I use on a regular basis, is !$. It expands to the last argument of the previous command. It's a useful shorthand in places.

share|improve this answer
4  
!! to fill in the complete last command entered is remarkably useful; particularly, sudo !! or pfexec !! – jgoldschrafe Dec 2 '10 at 11:20
2  
I also find sudo and pfexec to be nice utilities, but no need to be so enthusiastic. – LeartS Apr 17 '14 at 0:08
    
$_ works in more shells than bash and it's a proper variable, unlike !$. (and @LeartS: I liked your joke's lack of emoticons. ;) ) – ΤΖΩΤΖΙΟΥ 22 hours ago

Yes, ! is a special character to bash, it is used to refer to previous commands.

Few of the ways you can handle the situation

The following will output the string as it is

echo 'Reboot your instance!'

The following will execute the command and concatenate the string

echo 'escaping #'" adding `which python` to the string"
echo '#!'`which python`
share|improve this answer

In bash 4.3 it seems you no longer need to use single quotes or set +H:

$ bash --version
GNU bash, version 4.3.46(1)-release (x86_64-unknown-linux-gnu)
[...]
$ echo "Reboot your instance!"
Reboot your instance!
share|improve this answer

Just put a space between ! and " than it'll work.

Cheers.

share|improve this answer
1  
Could you please add an explanation as to why your solution works? – 200_success Sep 26 '14 at 8:20
2  
This works because Bash only treats ! as a special character if it's directly followed by a non-whitespace character. However, it will also add an extra blank to your output, so that might not always be desired... – mmey Oct 2 '14 at 4:50

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.