Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

echo "#!" fails -- "event not found"

Tags:

bash

echo

The following fails and I don't understand why:

$ echo "#!"

the following also fails with the same error message:

$ echo "\#!"

the error message:

-bash: !": event not found

Why does it fail? How should the echo be done instead?

like image 732
erikbstack Avatar asked Aug 05 '12 11:08

erikbstack


People also ask

What you mean by Echo?

: the repetition of a sound caused by reflection of sound waves. : the sound due to such reflection. : a repetition or imitation of another : reflection.

How does Echo do work?

Here's how that works: Whenever you ask Alexa a question or give her a command, the Echo records the audio and uploads the snippet to Amazon's cloud servers. Those servers translate the audio into text, then figure out the best way for Alexa to answer.

What is the difference between Echo and Echo?

The main difference between the echo and Echo Dot is the speaker: The Echo Dot is essentially the top portion of the regular Amazon Echo, without the beefy speaker underneath it. Instead, The Echo Dot is designed to be hooked up to a set of external speakers.


2 Answers

The ! character is used for csh-style history expansion.

If you do not use this feature, set +o histexpand (aka set +H) turns off this behavior. It is turned off for scripts, but often enabled for interactive use. In such cases, my personal recommendation is to turn it off permanently by adding set +o histexpand to your .bash_profile (or .bashrc if you don't have a .bash_profile; this is more complex than I want to try to fit into a parenthetical).

As a workaround, if for some reason you cannot or don't want to turn off and forget about this legacy csh feature, you can use single quotes instead of double quotes -- keeping in mind, of course, their different semantics. If you need to combine quoting with variable interpolation, for example, you can change

echo "#!$SHELL"  # oops, history expansion breaks this

into

 echo '#!'"$SHELL"

(notice the adjacent single-quoted and double-quoted strings; after the shell is done with this, the quotes will be removed and the string #! will be output next to the value of the variable SHELL with no space between them) or a number of other common workarounds like

 printf '#!%s\n' "$SHELL"

... though as remarked in a comment, even single quotes don't necessarily prevent this from happening when they are at the end of a pipeline.

like image 166
tripleee Avatar answered Oct 14 '22 00:10

tripleee


By default, bash supports csh compatible history-expansion.

In bash

echo #!

will only print a newline, as # starts a comment.

In

echo "#!"

the # is part of the string started with ". Such strings are still inspected by bash for special characters. ! is a special character iff it is followed by any other text.

-bash: !": event not found

In this case, bash expects the !" token to refer to a previous command in shell history starting with ", and does not find one. All by itself, ! will not trigger this behaviour:

$ echo \# !
# !

$ echo fee ! fie
fee ! fie

Finally,

$ echo !echo

produces two lines, the first line is printed by the shell to show how the pattern above expands to:

echo echo '# !'

while the second line is just the result of executing the expanded command: echo # !


See Also: The Bash man page on History Expansion

like image 43
Henk Langeveld Avatar answered Oct 14 '22 00:10

Henk Langeveld