在管道後使用多個參數運行多次相同的命令

在管道後使用多個參數運行多次相同的命令

我有一個由 產生的密鑰(隨機二進位資料)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

相關內容