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 - моя оболочка.

2 ответа2

0

Краткий ответ: смотрите 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 в двойные кавычки, чтобы его значение не подвергалось второй половине процесса разбора оболочки.

0

Попробуйте изменить $D $2 ${ERR} | $D - ${ERR} чтобы:

$( $D $2 ${ERR} | $D - ${ERR} )

Также используйте полный путь к вашей программе gpg , например:

/usr/local/bin/gpg

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .