以下は、2 つの異なる対称暗号を順番に使用してファイルを対称的に暗号化/復号化するスクリプトです。
#!/bin/bash
if [ "$#" -ne 2 ]; then
echo "Arguments: enc|dec filename"
exit
fi
E="gpg -o - --symmetric --cipher-algo"
D="gpg -o - --decrypt"
ERR="2>/dev/null"
if [ "$1" = "enc" ]; then
$E AES $2 | $E TWOFISH -
elif [ "$1" = "dec" ]; then
$D $2 ${ERR} | $D - ${ERR}
else
echo "Arguments: enc|dec filename"
exit
fi
実行すると./doublecrypt dec /tmp/test.encrypted
エラーが発生します
usage: gpg [options] --decrypt [filename]
usage: gpg [options] --decrypt [filename]
ラインを変えたら
$D $2 ${ERR} | $D - ${ERR}
に
echo "$D $2 ${ERR} | $D - ${ERR}"
印刷します
gpg -o - --decrypt /tmp/xenc 2>/dev/null | gpg -o - --decrypt - 2>/dev/null
これを bash にコピーして貼り付けると、正しく実行されます。
echo
では、 を削除して、元の形式のように bash スクリプトで直接評価すると、なぜ機能しないのでしょうか?
私は Ubuntu Saucy を実行しており、シェルは bash です。
答え1
短い答え:参照BashFAQ #50: 変数にコマンドを入れようとしていますが、複雑なケースでは常に失敗します。。
長い答え: シェルがコマンドラインのさまざまな要素を解析する順序が原因で問題が発生しています。具体的には、変数参照 ( など${ERR}
) は、プロセスの約半分の時点で展開されます。つまり、引用符やエスケープ、リダイレクトなどの処理が終わった後です。あなたの場合、重要なのはリダイレクトの部分です。シェルが${ERR}
に展開するまでに2>/dev/null
、リダイレクトが検索されて見つからなかったので、シェルは を2>/dev/null
コマンドの引数として扱い、gpg
それを意味がないとして拒否します。
基本的に、コマンド (またはコマンド要素) を変数に格納するのは間違った方法です。変数はデータ用であり、実行可能コード用ではありません。この場合は、代わりに関数を使用する方がはるかに適切です。
e() {
gpg -o - --symmetric --cipher-algo "$@"
}
d() {
gpg -o - --decrypt "$@" 2>/dev/null
}
if [ "$1" = "enc" ]; then
e AES "$2" | e TWOFISH -
elif [ "$1" = "dec" ]; then
d "$2" | d -
else
echo "Arguments: enc|dec filename"
exit
fi
$2
また、その値がシェル解析プロセスの後半で処理されないように、二重引用符で囲んでいることにも注意してください。
答え2
次のように変更してみてください$D $2 ${ERR} | $D - ${ERR}
:
$( $D $2 ${ERR} | $D - ${ERR} )
また、プログラムへのフルパスを使用しますgpg
。例:
/usr/local/bin/gpg