在管道之後多次執行帶有多個參數的相同命令
我有一個密鑰(隨機二進制數據),由
get_key
.有了這個密鑰,我可以對我的加密文件做幾件事。例如,我可以解密它們。
get_key | tee >(decrypt file1) >(decrypt file2)
我想知道如何將其推廣到
n
文件以FILES=file1 file2 file3 file4 file5
.目前,我可以看到兩種解決方案:
1)計算一個字元串和
eval
它
f
2)如果數組不為空,則用呼叫decrypt的遞歸函式替換decrypttee >(decrypt A[0]) | f ("${A[@]:1}")
(它解密第一個元素並遞歸呼叫自身)如果它是空的,則什麼都沒有。我想知道您是否有更好的方法來執行此操作(請注意,我不希望將密鑰寫入文件或變數,因此不能選擇循環)。
在循環中創建 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
鑑於您的案例,在完全生成密鑰之前開始執行解密是沒有意義的,因此在完成之前您不需要啟動
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
一個包含必要的字元串<(…)
(注意棘手的引用)。