Aqui está um script que criptografa/descriptografa simetricamente um arquivo com duas cifras simétricas diferentes em sequência.
#!/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
Quando executo ./doublecrypt dec /tmp/test.encrypted
recebo os erros
usage: gpg [options] --decrypt [filename]
usage: gpg [options] --decrypt [filename]
Se eu mudar a linha
$D $2 ${ERR} | $D - ${ERR}
para
echo "$D $2 ${ERR} | $D - ${ERR}"
Ele imprime
gpg -o - --decrypt /tmp/xenc 2>/dev/null | gpg -o - --decrypt - 2>/dev/null
Se eu copiar e colar no bash, ele será executado corretamente.
Então, por que não funciona se eu remover echo
e deixar o script bash avaliá-lo diretamente, como na forma original?
Estou executando o Ubuntu Saucy e o bash é meu shell.
Responder1
Resposta curta: vejaBashFAQ #50: Estou tentando colocar um comando em uma variável, mas os casos complexos sempre falham!.
Resposta longa: você está tendo problemas por causa da ordem em que o shell analisa vários elementos das linhas de comando; especificamente, ele expande referências de variáveis (como ${ERR}
) na metade do processo - depois de já ter lidado com coisas como aspas, escapes e redirecionamentos. No seu caso, é a parte dos redirecionamentos que importa: no momento em que o shell se expande ${ERR}
para 2>/dev/null
, ele já procurou por redirecionamentos e não encontrou nenhum, então ele apenas trata 2>/dev/null
como um argumento para o comando e depois gpg
rejeita isso como sem sentido.
Basicamente, armazenar comandos (ou elementos de comando) em variáveis é a maneira errada de fazer isso. Variáveis são para dados, não para código executável. Nesse caso, seria muito melhor usar funções:
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
Observe que também coloquei $2
aspas duplas, para evitar que seu valor seja submetido à segunda metade do processo de análise do shell.
Responder2
Tente mudar $D $2 ${ERR} | $D - ${ERR}
para:
$( $D $2 ${ERR} | $D - ${ERR} )
Além disso, use o caminho completo para o seu gpg
programa, por exemplo:
/usr/local/bin/gpg