Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I am trying to decrypt a file in a script with gpg batch mode, but command is not executed because the passphrase contains a "!"

echo "m!pass"|gpg --batch --passphrase-fd 0 --decrypt-file plain.gpg
bash: !pass": event not found


gpg --batch --passphrase "m!pass" -d plain.gpg 
bash: !pass": event not found

I guess bash is interpreting the exclamation mark as a reference to the command execution history. Which would be the right way to do it in GPG batch mode?

share|improve this question
up vote 5 down vote accepted

Use single quotes instead of double:

$ echo "m!pass"
bash: !pass": event not found
$ echo 'm!pass'

This is quite nicely explained in the bash manual (emphasis added):

Single Quotes

Enclosing characters in single quotes (‘'’) preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.

Double Quotes

Enclosing characters in double quotes (‘"’) preserves the literal value of all characters within the quotes, with the exception of ‘$’, ‘’, ‘\’, and, when history expansion is enabled, ‘!’. The characters ‘$’ and ‘’ retain their special meaning within double quotes (see Shell Expansions). The backslash retains its special meaning only when followed by one of the following characters: ‘$’, ‘`’, ‘"’, ‘\’, or newline. Within double quotes, backslashes that are followed by one of these characters are removed. Backslashes preceding characters without a special meaning are left unmodified. A double quote may be quoted within double quotes by preceding it with a backslash. If enabled, history expansion will be performed unless an ‘!’ appearing in double quotes is escaped using a backslash. The backslash preceding the ‘!’ is not removed.

share|improve this answer

My preferred method is to just disable the stupid history expansion feature you never heard of and never wanted and will likely never use even though you now know about it:

$ echo "hello!"
bash: !": event not found

$ set +o histexpand

$ echo "hello!"
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.