Bash:在许多文件上并行化md5sum校验和

时间:2013-05-27 11:28:29

标签: bash

比方说,我有一个64核服务器,我需要计算md5sum中所有文件的/mnt/data,并将结果存储在一个文本文件中:

find /mnt/data -type f -exec md5sum {} \; > md5.txt

上述命令的问题是,在任何给定时间只运行一个进程。我想利用我的64核的全部功能。理想情况下,我想确保在任何给定时间,64个并行md5进程正在运行(但不超过64个)。

另外。我需要将所有进程的输出存储到一个文件中。

注意:我不是在寻找一种并行计算一个文件md5sum的方法。我正在寻找一种方法来并行计算64个不同文件的64 md5sums,只要有来自find的文件。

4 个答案:

答案 0 :(得分:19)

使用GNU parallel。您可以找到更多关于如何实现它的示例here

find /mnt/data -type f | parallel -j 64 md5sum > md5.txt

答案 1 :(得分:8)

你也可以使用xargs,它可能比某些发行版上的并行更多。

-P控制产生的进程数。

find /mnt/data -type f | xargs -L1 -P24  md5sum > /tmp/result.txt

答案 2 :(得分:6)

如果您想要实验,请尝试安装md5deep。 (http://md5deep.sourceforge.net

Here is the manual您可以在这里阅读:

  

-jnn控制多线程。默认情况下,程序将创建一个生产者线程来扫描文件系统,每个CPU创建一个散列线程   核心。多线程导致输出文件名在   非确定性顺序,因为需要更长时间才能进行散列的文件   在他们被散列时延迟了。如果需要确定性订单,   指定-j0以禁用多线程

如果这没有帮助,则会产生I / O瓶颈。

答案 3 :(得分:1)

<强>已更新

如果您不想使用其他软件包,可以尝试使用以下方法:

#!/usr/bin/bash

max=5;
cpid=()

# Enable job control to receive SIGCHLD
set -m
remove() {
  for i in ${!cpid[*]}; do
    [ ! -d /proc/$i ] && echo UNSET $i && unset cpid[$i] && break
  done
}
trap remove SIGCHLD

for x in $(find ./ -type f -name '*.sh'); do
  some_long_process $x&
  cpid[$!]="$x";
  while [ ${#cpid[*]} -ge $max ]; do
    echo DO SOMETHING && sleep 1;
  done
done
wait

如果子进程退出,它首先允许接收SIGCHLD。如果SIGCHLD找到第一个不存在的进程并从cpid数组中删除。

在for循环中,异步启动maxsome_long_process个进程。它max到达它会轮询添加到cpid数组的所有pid。它等待cpid的长度小于max,并异步启动更多进程。

如果列表结束,则等待所有孩子完成。

<强> ADDED

最后,我找到了一个合适的解决方案here