To be able to disable history expansion on a particular command line, you can use space
as the 3rd character of $histchars
:
histchars='!^ '
Then, if you enter your command with a leading space, history expansion will not be performed.
bash-4.3$ echo "#!/bin/bash"
bash: !/bin/bash: event not found
bash-4.3$ echo "#!/bin/bash"
#!/bin/bash
Note however that leading spaces are also used when $HISTCONTROL
contains ignorespace
as a way to tell bash
not to record a command line in the history.
If you want both features indenpendantly, you'll need to choose another character as the 3rd character of $histchars
. You want one that doesn't affect the way your command is interpreted. A few options:
- using backslash (
\
): \echo foo
works but that has the side effect of disabling aliases or keywords.
- TAB: to insert it in first position, you need to press Ctrl+VTab though.
if you don't mind typing two keys, you can pick any character that normally doesn't appear in first position (%
, @
, ?
, pick your own) and make an empty alias for it:
histchars='!^%'
alias %=
Then enter that character, space and your command:
bash-4.3$ % echo !!
!!
(you won't be able not to record a command where history substitution has been disabled though. Also note that the default 3rd character of $histchars
is #
so that history expansion is not done in comments. If you change it, and you enter comments at the prompt, you should be aware of the fact that ! sequences may be expanded there).