嗯,任务很简单:我的脚本的一部分必须计算 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]}