这是一个脚本,它依次使用两个不同的对称密码对文件进行对称加密/解密。
#!/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 是我的 shell。
答案1
简短回答:参见BashFAQ #50:我尝试将命令放入变量中,但复杂的情况总是失败!。
长答案:您遇到麻烦是因为 shell 解析命令行各种元素的顺序;具体来说,它${ERR}
在处理完引号、转义符和重定向等内容后,大约在处理了一半的变量引用(如)。对于您来说,重定向部分很重要:当 shell 扩展${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
在双引号中,以防止其值受到 shell 解析过程的后半部分的影响。
答案2
尝试更改$D $2 ${ERR} | $D - ${ERR}
为:
$( $D $2 ${ERR} | $D - ${ERR} )
另外,使用程序的完整路径gpg
,例如:
/usr/local/bin/gpg