太多的管道对性能不利

2 unix bash shell

我使用该bash命令搜索文件并在我的本地系统上执行md5dsum.在我看来,这个命令在大型vendor目录上表现不佳.是否有更好的风格而不是使用更高性能的管道?

find ./vendor -type f -print0 | sort -z | xargs -0 md5sum | grep -vf /usr/local/bin/vchecker_ignore > MD5sums
Run Code Online (Sandbox Code Playgroud)

Max*_*kin 7

sort这里介绍阻塞:它必须等到find完成才能输出结果.find在大型文件系统上,尤其是使用hdd或nfs,可能需要一段时间.

您可能希望在最后排序以允许md5sum与...并行运行find,例如:

find ./vendor -type f -print0 | xargs -0 md5sum | grep -vf /usr/local/bin/vchecker_ignore | sort -k2 > MD5sums
Run Code Online (Sandbox Code Playgroud)

md5sum可能需要一些时间来处理大文件.您可能希望使用GNU运行它,parallel而不是xargs在有很多文件或文件很大的情况下运行它.


您可能还喜欢使用行缓冲模式.在这种情况下,它需要使用新行分隔符作为文件名(禁止文件名中的新行符号,这将是相当不寻常的)而不是0分隔符,以便行缓冲模式工作.例如:

stdbuf -oL find ./vendor -type f | stdbuf -oL grep -vf /usr/local/bin/vchecker_ignore | xargs -n50 -d'\n' md5sum | sort -k2 > MD5sums
Run Code Online (Sandbox Code Playgroud)

上面的命令将首先过滤每个文件grep,然后md5sum对50个文件批量执行.对于小文件,您可能需要更大批量(并且可能完全删除stdbuf -oL),对于大文件 - 更小.

  • 可以在*md5sum调用之后排序*(通过第2列,md5sum的文件名输出); 理想情况下,这将允许哈希计算在搜索仍在运行时启动; 一个是磁盘,另一个是CPU,所以可能有一个真正的好处.也许应该使用`unbuffer`或`stdbuf`(参见https://unix.stackexchange.com/questions/25372/turn-off-buffering-in-pipe)让md5sum立即启动. (2认同)