使用 xargs 并行运行程序

我现在有当前的脚本。

#!/bin/bash
# script.sh


for i in {0..99}; do
script-to-run.sh input/ output/ $i
done

我希望使用 xargs 并行运行它,我已经试过了

script.sh | xargs -P8

但是上面的操作一次只执行一次。 在脚本 for 循环中要执行的行的末尾添加 & 将尝试同时运行该脚本99次。如何执行循环,一次只执行8个,总共执行100个。

120827 次浏览

来自 xargs手册页:

这个手册页记录了 xargs.xargs 读取项的 GNU 版本 从标准输入,由空格分隔(可以保护 使用双引号或单引号或反斜杠)或换行符,并执行 命令(默认值为/bin/echo)使用任意初始值-执行一次或多次 参数后跟从标准输入读取的项 忽略标准输入。

这意味着对于示例 xargs正在等待并收集脚本中的所有输出,然后运行 echo <that output>。没什么用,也不是你想要的。

The -n argument is how many items from the input to use with each command that gets run (nothing, by itself, about parallelism here).

要使用 xargs做你想做的事情,你需要做更多类似下面这样的事情(未经测试) :

printf %s\\n {0..99} | xargs -n 1 -P 8 script-to-run.sh input/ output/

就像这样。

  • 099,每行打印一个数字。
  • 运行 xargs
    • 每运行命令行取 最多一个参数
    • 并且一次运行 直至8个进程

使用 GNU 并行,您可以做到:

parallel script-to-run.sh input/ output/ {} ::: {0..99}

如果你想每个 CPU 核运行一个作业,那么加入 -P8

xargs相反,它会做正确的事情,即使输入包含空格,’,或“(但这里不是这种情况)。它还确保不同作业的输出不会混合在一起,因此如果使用输出,则可以保证不会从两个不同的作业获得半行。

GNU 并行是一个通用的并行程序,它使得在同一台计算机上或者在具有 ssh 访问权限的多台计算机上并行运行作业变得非常容易。

If you have 32 different jobs you want to run on 4 CPUs, a straight forward way to parallelize is to run 8 jobs on each CPU:

Simple scheduling

取而代之的是,当一个进程完成时,GNU 并行会生成一个新的进程——保持 CPU 处于活动状态,从而节省时间:

GNU Parallel scheduling

安装

If GNU Parallel is not packaged for your distribution, you can do a personal installation, which does not require root access. It can be done in 10 seconds by doing this:

$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 883c667e01eed62f975ad28b6d50e22a
12345678 883c667e 01eed62f 975ad28b 6d50e22a
$ md5sum install.sh | grep cc21b4c943fd03e93ae1ae49e28573c0
cc21b4c9 43fd03e9 3ae1ae49 e28573c0
$ sha512sum install.sh | grep da012ec113b49a54e705f86d51e784ebced224fdf
79945d9d 250b42a4 2067bb00 99da012e c113b49a 54e705f8 6d51e784 ebced224
fdff3f52 ca588d64 e75f6033 61bd543f d631f592 2f87ceb2 ab034149 6df84a35
$ bash install.sh

有关其他安装选项,请参见 http://git.savannah.gnu.org/cgit/parallel.git/tree/README

了解更多

查看更多例子: http://www.gnu.org/software/parallel/man.html

观看介绍视频: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Walk through the tutorial: http://www.gnu.org/software/parallel/parallel_tutorial.html

注册电子邮件列表以获得支持: https://lists.gnu.org/mailman/listinfo/parallel

您可以使用这个简单的1行命令

seq 1 500 | xargs -n 1 -P 8 script-to-run.sh input/ output/

下面是一个与 find并行运行命令的例子:

find -name "*.wav" -print0 | xargs -0 -t -I % -P $(nproc) flac %

-print0以空字节而不是换行结束文件名,因此我们可以在 xargs 中使用 -0来防止将空格作为两个独立参数处理的文件名。

-t意味着详细,使 xargs 打印它正在执行的每个命令,可能是有用的,如果不需要,删除。

-I %意味着用从标准输入读取的参数替换命令中出现的 %

-P $(nproc)意味着并行运行我们命令的最大 nproc实例(nproc打印可用处理单元的数量)。

flac %是我们的命令,从早期的 -I %意味着这将成为 flac foo.wav

参见: Xargs 手册(1)