パスワードに「!」が含まれている場合は、バッチモードでgpgを使用してファイルを復号化しますか?

パスワードに「!」が含まれている場合は、バッチモードでgpgを使用してファイルを復号化しますか?

gpgバッチモードを使用してスクリプト内のファイルの復号化を試みますが、パスワードに「!」が含まれているため、コマンドは実行されません。

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

私はbashが感嘆符をコマンド実行履歴への参照として解釈していると思います。 GPGバッチモードで正しい方法は何ですか?

答え1

二重引用符の代わりに一重引用符を使用してください。

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

これはバッシュマニュアル(強調する):

アポストロフィ

一重引用符( ''')で文字を囲むと、引用符内の各文字のリテラル値が保持されます。前にバックスラッシュがある場合でも、一重引用符の間に一重引用符を使用することはできません。

二重引用符

文字を二重引用符( ''')で囲むと、二重引用符内で’, ‘\’, and, when history expansion is enabled, ‘!’. The characters ‘$’ and ‘特別な意味を維持する '$'を除いて、二重引用符内のすべての文字のリテラル値が保持されます(シェル拡張を参照)。が来るときにのみ特別な意味を維持します。二重引用符内では、これらの文字の1つに続くバックスラッシュが削除されます。特別な意味を持たない先行バックスラッシュ文字は変更されません。二重引用符の前にバックスラッシュを追加すると、二重引用符の中に二重引用符を入れることができます。有効にすると、「!」が二重引用符内に表示され、バックスラッシュでエスケープされない限り、履歴拡張が実行されます。前の「!」のバックスラッシュは削除されません。

答え2

私が好むアプローチは、聞いたことがない、望んだことがない、おそらく今知っていても、おそらく絶対に使用しない愚かな履歴拡張機能を無効にすることです。

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

$ set +o histexpand

$ echo "hello!"
hello!

関連情報