Yes, history expansion is enabled by default only for interactive shells.
To enable it for a shell script, write:
set -H
To disable it in an interactive shell, write:
set +H
To determine whether or not history expansion is currently enabled, use some form of the following code:
case $- in (*H*) echo enabled ;; (*) echo disabled ;; esac
In starting to teach a shell class, I dug through the manual extensively to try to establish what an "interactive shell" really is. It's a whirlpool question, so let me save you some trouble:
The shell has MANY options. Some of these options are initialized in different ways when the shell has a controlling terminal (or when started with -i
, blah blah, whatever, see below).
ALL of the shell's options can be individually changed.
An "interactive shell" is a deceptive term when you try to define it precisely. It is really just a collection of option settings.
The question about which settings make a shell interactive or not is impossible to answer; it gets ridiculous. It is precisely the same philosophical question as the Ship of Theseus.
If you start an interactive shell, but then disable history expansion, use the --noediting
flag, set --norc
, turn off expand_aliases
, etc., etc., then in what sense is the shell interactive? Or, when does it become not interactive anymore? You can't answer these questions.
The truth is that "interactive" is just a convenient label for a collection of various shell options. Likewise "non-interactive." Same thing; just a collection of behaviors that can each one be changed individually.
Bottom line: the shell behaves differently when it is started "interactively" versus when it is started "non-interactively." Trying to precisely define these terms after start-up is silly. Just look at each individual option of the shell to understand its behavior.
I had forgotten that in addition to my own research, I posted about it extensively on this very site.
shopt
modifier to get it to work in your script. I know that's not really the answer you are looking for. – jesse_b Aug 09 '17 at 02:51!!
or!-2
(negative/relative history numbers) or similar. Mostly they would be solved better in other ways, but it's still a good question about how the shell works (and when you do/don't need to escape your exclams!). – Wildcard Aug 23 '17 at 06:27