Вопрос по bash, conditional, function, pipe, if-statement – Баш условных трубопроводов

4

Как я могу передать вывод команды на случай, если она вернет true?

<code>function open
{
    TEMPFILE=$(mktemp -u)
    if ! gpg2 --quiet --decrypt --batch --passphrase "$2" "$1" 2> $TEMPFILE; then
        error $"Password errata od errore di lettura dal file\n\nDettagli:\n$(grep -v '^$' $TEMPFILE)"
        rm -f $TEMPFILE
        return 1
    fi
    rm -f $TEMPFILE
}

if ! open "[email protected]" "$PASSWORD"; then
    exit 1
fi | <SOMECOMMAND>
</code>

Таким образом, он просто передает и не проверяет, возвращает ли open значение true или false, поэтому никогда не выполняет «выход 1».

Как я могу решить это без использования файлов (по соображениям безопасности).

Полные источники:fpasswd-0.2-alpha on SourceForge Stefano d'Antonio

Ваш Ответ

3   ответа
0

mkfifo piper;
open "[email protected]" "$PASSWORD"; retval=$? > piper &
if [ x"$retval" != x0 ]
then
   rm piper
   exit 1
fi
<SOMECOMMAND> < piper
rm piper
Просто понял, что я слишком упростил свой тест до такой степени, что удалил & amp; упс, моя ошибка
Как я уже сказал, я не хочу использовать ни файл, но и именованные каналы, содержимое полно паролей в виде открытого текста. Stefano d'Antonio
Не будет работать. Во-первых, retval устанавливается в подоболочку (из-за&). Во-вторых,open ... Команда, вероятно, заблокирует ожидание чтения данных из канала, но ничто не может прочитать из канала до тех пор, покаopen ... отделки.
Не работал для меня. Я старалсяfalse; retval=$? >/dev/null &дождался его окончания, потомecho $retval и получил пустую строку. Что касается блокировки команды open, если вы попытаетесь записать слишком много в канал (обычно 64 КБ, см.here), процесс записи будет блокировать ожидание чего-либо, чтобы прочитать данные и освободить место в канале.
Я только что проверил это (хотя явно не использовал open), и оно работало как ожидалось ... как при неудачной отправке команды в pipe, так и при успешном вводе оператора then, когда это необходимо. И команда open пишет в канал, а не читает
8

позвольте мне объяснить, что это сложнее, чем вы думаете. Основная проблема заключается во времени:open ... функция выдает результат во время работы; выдает статус выходаafter it has finished running (и, следовательно, после того, как он произвел свою продукцию). Так как вы хотите делать с выходом разные вещи в зависимости от состояния выхода, вы должны хранить выходные данные где-то временно, пока не завершится функция, и вы не сможете решить, что делать с выходом.

Канал по своей сути не будет работать для этого, потому что каналы не хранят данные (за исключением небольшого буферного пространства) - они передают данные «вживую». от одной программы к другой, и в этом случае вторая программа не может начаться до тех пор, пока не завершится первая. Обычно временный файл идеально подходит для этого (хранение данных - это то, для чего нужны файлы), но вы этого не хотите по соображениям безопасности. Это в значительной степени оставляет размещение данных где-то в ОЗУ (хотя это тоже не совсем безопасно ...).

Ответ @Karoly Horvath предложил сохранить выходные данные в переменной bash (которая хранится в RAM), но это не сработало, потому что bash не справляется с нулевыми байтами в значениях переменных. Итак, я предлагаю вариант, в котором вы используете «безопасный» кодирование данных и поместите это в переменную bash. Я использовал формат uuencode, но вы также можете использовать base64, hex dump и т.д ...

if result=$(open "[email protected]" "$PASSWORD" | uuencode -; exit ${PIPESTATUS[0]}); then
    echo "$result" | uudecode -p | SOMECOMMAND
fi

Обратите внимание, что PIPESTATUS - это bashism, поэтому вы должны запустить скрипт с#!/bin/bash, Кроме того, если вывод слишком длинный, вы можете столкнуться с ограничениями того, сколько данных bash хочет хранить / расширять / и т. Д .; если это оказывается проблемой, все становится сложнее.

Кстати, если вы беспокоитесь о безопасности, не используйте gpg2.--passphrase опция - передача ключевой фразы в командной строке предоставляет ее, например, любой, кто бежитps в нужное время, что очень плохая идея. У gpg2 есть много вариантов ввода ключевой фразы, поэтому, пожалуйста, используйте более подходящую.

В этой ситуации это выглядит как лучший способ сделать это.
Да, я уже попробовал. Так это лучший способ? Stefano d'Antonio
Однако, пока я искал альтернативу, я использовал «open» функционировать два раза, один раз для проверки (& gt; / dev / null) и другой для использования данных ... Но это пустая трата ресурсов и времени. (Однако парольная фраза находится в ps всего на несколько секунд, но вы абсолютно правы, я не должен использовать --passphrase) Stefano d'Antonio
Спасибо, позже я попробую использовать uuencode и сообщу. Спасибо также за объяснение; теперь я буду использовать & quot; echo $ PASS | gpg2 -d --batch --passphrase-fd 0 $ FILE & quot ;, это безопасно, верно? Stefano d'Antonio
Да, используяecho "$PASSWORD" | gpg2 ... --passphrase-fd 0 (обратите внимание на двойные кавычки вокруг$PASSWORD) должен быть безопасным, потому чтоecho запускается не как обычная команда, а как встроенная в подоболочку, поэтому ее аргумент не виденps и тому подобное.
0

если файл открывается успешно:

   result=open "[email protected]" "$PASSWORD"
    if [ $? -gt 0 ]; then
      exit 1
    fi
    echo "$result" | <SOMECOMMAND>
новая строка не является проблемой ... какова ваша SOMECOMMAND?
перенаправить вывод в файл, который сохранит все ..
@ Нет. Вы всегда должны заключать в кавычки вывод подпроцесса. пытатьсяresult="$(open [email protected] $PASSWORD)" (я ненавижу клещей)
Вы правы в отношении новой строки, но она также содержит другие непечатаемые символы (например, \ 0), которые не сохранились. SOMECOMMAND - это функция, которая печатает пароли (через графическое представление, если графическое изображение, стандартный вывод, если нет). Я не могу использовать файл по соображениям безопасности. Stefano d'Antonio
выходные данные open содержат новую строку и другие непечатные символы, они не работают подобным образом. Stefano d'Antonio

Похожие вопросы