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).
echo, is it always better to using'instead of"? – Zen Feb 07 '15 at 05:40$''. For exampleecho $'1!\n2!\n3!\n'prints each number followed by a bang and a newline. – spelufo Feb 19 '15 at 14:34'"$var"'... single quote - double quote - variable - double quote - single quote. http://askubuntu.com/a/76842/334235 – phyatt Nov 07 '16 at 18:12!:echo '#!'"/bin/bash\nMore $things"– ejoubaud Dec 08 '16 at 13:08echo '0123'"$var"'456', note two pairs of single quotes and one pair of double quotes. – phyatt Apr 09 '18 at 19:26