Выполнение одной и той же команды несколько раз с несколькими аргументами после символа «труба»

Выполнение одной и той же команды несколько раз с несколькими аргументами после символа «труба»

У меня есть ключ (случайных двоичных данных), который генерируется get_key.

И с этим ключом я могу сделать несколько вещей с моими зашифрованными файлами. Например, я могу их расшифровать.

get_key | tee >(decrypt file1) >(decrypt file2)

Я хотел бы знать, как это можно обобщить для nфайлов, которые указаны как FILES=file1 file2 file3 file4 file5.

На данный момент я вижу два решения:

1) Вычислите строку и evalона

2) заменить decrypt рекурсивной функцией f, которая вызывает decrypt tee >(decrypt A[0]) | f ("${A[@]:1}")(она расшифровывает первый элемент и вызывает себя рекурсивно), если массив не пустой, и ничего, если пустой.

Я хотел бы узнать, есть ли у вас более удобный способ сделать это (обратите внимание, что я не хочу, чтобы ключ был записан в файл или переменную, поэтому циклы не подходят).


Редактировать: Я буду использовать это вhttps://github.com/xavierm02/combine-keys

решение1

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

Сохранение вывода в переменной — самый простой способ. Однако, поскольку это двоичные данные, которые могут содержать нулевые байты,это работает только в zsh, в других оболочках не работает. Если вы беспокоитесь о безопасности, не беспокойтесь: злоумышленник, который может наблюдать за содержимым переменной, также может запустить ее get_keyи просмотреть ее вывод.

key=$(get_key)
for file in $FILES; do
  print -rn -- $key | decrypt $file
done

В других оболочках вы можете использовать временный файл. Убедитесь, что вы сделали его доступным для чтения только вам. Если временный файл находится в файловой системе на диске, то есть небольшой риск утечки ключа, если жесткий диск сервера будет украден в неподходящее время. Если файл находится в файловой системе в памяти, такого риска нет.

key_file=$(umask 077; mktemp)
get_key >"$key_file"
for file; do
  decrypt "$file" <"$key_file"
done
rm "$key_file"

Если вы не хотите использовать временный файл и у вас нет zsh, вы можете использовать другой язык, например Perl или Python.

perl -e '
    $key = `get_key`;
    foreach (@ARGV) {
        open KEY, "|-", "decrypt", $_ or die $!;
        print KEY $key or die $!;
        close KEY or die $!;
    }'

Если у вас нет языка лучше, чем POSIX shell или ksh или bash, и вы не можете использовать временный файл, то вам придется вернуться к конвейеризации tee(или выполнить сложное кодирование и декодирование). Чтобы справиться с переменным количеством выходов, вы можетесоздать один fifo на выход, или построить и evalстроку, содержащую необходимое <(…)(остерегайтесь хитрого кавычек).

решение2

Создайте FIFO в цикле и заставьте ваши decrypts ждать, пока они будут записаны:

for i in "${A[@]}";do
    mkfifo /tmp/"$i"_fifo
    decrypt "$i" </tmp/"$i"_fifo &
done
getkey | tee >/dev/null /tmp/*_fifo
rm -f /tmp/*_fifo

Связанный контент