嗯,任務很簡單:我的腳本的一部分必須計算 md5 和 sha1 雜湊。輸入是一個檔案(大檔案),必須將雜湊值放入 MD 和 SH 變數中以供以後的輸出組合。
雖然處理的檔案非常大(數百 GB),但我嘗試使用某種讀取後多次使用的資料。我發現了一種叫做流程替換的東西,我以下面的方式採用了它:
$ dd if=big.tgz 2>/dev/null |tee >(sha1sum ) > >(md5sum ) ;
代替:
$ SH=$(sha1sum big.tgz); MD=$(md5sum big.tgz);
但我發現了下一個:
顯然沒有資源,也沒有節省時間,因為兩者都需要大約。 40 秒(適用於 4.776 GB 檔案)
我不知道如何將子進程的結果保存
>(md5sum )
到變數 MD 中以便稍後在腳本中使用它
我試圖理解 pipelinexec,但即使是漂亮的彩色插圖也沒有成功。
除了 VAR=$(command) 之外,還有其他方法可以將輸出重新導向到變數嗎?
答案1
在效能方面,您可能會受到 CPU 的限制。實際上,MD5 和 sha1sum 在 40 秒內傳輸 4.7TB 感覺很快。所以即使你這樣工作。值得一提的是,您將減少磁碟 IO。
你真的不需要這樣做dd
。您也可以將 sha1sum 和 md5sum 的輸出直接寫入檔案以供以後使用
tee < big.tgz >(sha1sum > big.tgz.sha1 ) > >(md5sum > big.tgz.md5 )
sha1=`cat big.tgz.sha1`
md5=`cat big.tgz.md5`
我建議使用像這樣的臨時檔案(big.tgz.sha1
和big.tgz.md5
),因為據我所知,沒有辦法同時設定兩個具有不同值的變數。您可以將其中一個直接捕獲到變數中,但不能同時捕獲兩者。允許md5sum
和sha1sum
同時寫入同一個標準輸出可能會導致不可預測的問題。
答案2
好吧,你可以在裡面添加另一個重定向:
tee < big.tgz >(sha1sum > big.tgz.sha1sum) >(md5sum > big.tgz.md5sum)
您也可以按原樣獲取輸出,因為很容易區分 sha1 和 md5(長度不同,因此不會混淆哪個是哪個)。
還有一些實用程式可以自行計算多個校驗和,而無需使用tee
.
實際上上面的內容也可以不寫tee
:
sha1sum big.tgz > big.tgz.sha1sum &
md5sum big.tgz > big.tgz.md5sum
wait # for sha1sum
從理論上講,這很糟糕,因為資料從磁碟讀取兩次。
實際上,並行(和後台)運行兩個讀取器應該允許磁碟快取來處理它,以便資料實際上仍然只讀取一次。這假設雜湊計算很快而 I/O 很慢,因此沒有進程可以逃離另一個進程。
(我之前發布過關於在另一個上下文中閱讀兩次的文章:將 pv 與 md5sum 一起使用- 雖然它通常有效,但存在一些風險,因此tee
仍然是更可靠的方法。 )
答案3
parset
GNU Parallel 用於並行設定變量,並將--tee
輸入傳送到多個命令:
parset md5,sha1,sha256 --pipe --tee {} ::: md5sum sha1sum sha256sum < bigfile
echo $sha1
parset sumarr --pipe --tee {} ::: md5sum sha1sum sha256sum < bigfile
echo ${sumarr[1]}