我有一个由 生成的密钥(随机二进制数据)get_key
。
有了这个密钥,我可以用我的加密文件做一些事情。例如,我可以解密它们。
get_key | tee >(decrypt file1) >(decrypt file2)
我想知道如何将其推广到n
文件以FILES=file1 file2 file3 file4 file5
.
目前,我可以看到两种解决方案:
eval
1 )计算一个字符串
f
2)如果数组不为空,则用调用解密的递归函数替换解密tee >(decrypt A[0]) | f ("${A[@]:1}")
(它解密第一个元素并递归地调用自身),如果数组不为空则什么也没有。
我想知道您是否有更好的方法来做到这一点(请注意,我不希望将密钥写入文件或变量,因此循环不是一种选择)。
答案1
根据您的用例,在密钥完全生成之前开始运行解密是没有意义的,因此您不需要decrypt
在get_key
完成之前启动进程。因此管道没有任何优势,您不妨将输出存储在get_key
某个地方并在以后使用它。
将输出存储在变量中是最简单的方法。但是,由于这是可以包含空字节的二进制数据,这只适用于 zsh,不适用于其他 shell。如果您担心安全性,请不要担心:可以观察变量内容的攻击者也可以运行get_key
并观察其输出。
key=$(get_key)
for file in $FILES; do
print -rn -- $key | decrypt $file
done
在其他 shell 中,您可以使用临时文件。请务必将其设置为只有您自己可读。如果临时文件位于磁盘文件系统上,那么如果服务器的硬盘在错误的时间被盗,则存在密钥泄露的小风险。如果文件位于内存文件系统上,则不存在此类风险。
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