У меня есть ключ (случайных двоичных данных), который генерируется 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 в цикле и заставьте ваши decrypt
s ждать, пока они будут записаны:
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