I have a simple bash script called foo.sh like this:
#!/bin/bash
echo "Foo!"
When I run it as ./foo.sh
I get the Foo!
message and everything's fine.
But if I echo "Foo!"
directly from the console, then I obtain the expected behavior and message: bash: !": event not found
.
I understand that the !
is presented as a previous command and if used inside p.e. single quotes, then it's considered as a literal.
I'm just wondering what is the difference here that running a script with that echo "Foo!"
(even with source ./foo.sh
works but directly from the console it doesn't.
Best Answer
By default, interactive bash shells have history expansion enabled (which is what controls the behaviour of
!
). Sourced files (which exist largely outside of the concept of history expansion) and scripts do not. Fromman bash
(or the online manual):This behaviour can be adjusted manually with
set [+-]H
, orset [+-]o histexpand
, where-H
/-o
enables history expansion, and+H
/+o
disables it.See also e.g.: