Shell

在管道之後多次執行帶有多個參數的相同命令

  • April 26, 2016

我有一個密鑰(隨機二進制數據),由get_key.

有了這個密鑰,我可以對我的加密文件做幾件事。例如,我可以解密它們。

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

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

目前,我可以看到兩種解決方案:

1)計算一個字元串和eval

f2)如果數組不為空,則用呼叫decrypt的遞歸函式替換decrypt tee >(decrypt A[0]) | f ("${A[@]:1}")(它解密第一個元素並遞歸呼叫自身)如果它是空的,則什麼都沒有。

我想知道您是否有更好的方法來執行此操作(請注意,我不希望將密鑰寫入文件或變數,因此不能選擇循環)。


編輯:我將在https://github.com/xavierm02/combine-keys中使用它

在循環中創建 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一個包含必要的字元串<(…)(注意棘手的引用)。

引用自:https://unix.stackexchange.com/questions/128548