在管道后使用多个参数运行多次相同的命令

在管道后使用多个参数运行多次相同的命令

我有一个由 生成的密钥(随机二进制数据)get_key

有了这个密钥,我可以用我的加密文件做一些事情。例如,我可以解密它们。

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

我想知道如何将其推广到n文件以FILES=file1 file2 file3 file4 file5.

目前,我可以看到两种解决方案:

eval1 )计算一个字符串

f2)如果数组不为空,则用调用解密的递归函数替换解密tee >(decrypt A[0]) | f ("${A[@]:1}")(它解密第一个元素并递归地调用自身),如果数组不为空则什么也没有。

我想知道您是否有更好的方法来做到这一点(请注意,我不希望将密钥写入文件或变量,因此循环不是一种选择)。


编辑:我将使用它https://github.com/xavierm02/combine-keys

答案1

根据您的用例,在密钥完全生成之前开始运行解密是没有意义的,因此您不需要decryptget_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,并让您的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

相关内容