使用xargs并行运行程序

Oli*_*ier 70 parallel-processing bash xargs

我目前有当前的脚本.

#!/bin/bash
# script.sh

for i in {0..99}; do
   script-to-run.sh input/ output/ $i
done
Run Code Online (Sandbox Code Playgroud)

我希望使用xargs并行运行它.我试过了

script.sh | xargs -P8
Run Code Online (Sandbox Code Playgroud)

但这样做只在当时执行一次.也没有运气-n8.添加&在脚本for循环中执行的行的末尾将尝试一次运行脚本99次.如何在当时仅执行8次循环,最多100次.

Eta*_*ner 101

xargs手册页:

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

这意味着您的示例xargs正在等待并从脚本中收集所有输出然后运行echo <that output>.不完全是有用的,也不是你想要的.

-n参数是如何从输入的许多项目与每个被运行(没什么,本身有关并行这里)命令使用.

要做你想做的事,xargs你需要做更像这样的事情(未经测试):

printf %s\\n {0..99} | xargs -n 1 -P 8 script-to-run.sh input/ output/
Run Code Online (Sandbox Code Playgroud)

哪个像这样打破了.

  • printf %s\\n {0..99}-从打印每行一个数099.
  • xargs
    • 最多每次运行命令行一个参数
    • 并且一次最多运行八个进程

  • 实际上你不需要将参数放在不同的行上; xargs word-splits.所以`echo {0..99} |`也可以.`<<< {0..99}`似乎不起作用; 虽然`<<< word`被记录为支撑扩展词,但是我没有使用任何版本的bash. (7认同)
  • 演示: `time head -12 &lt;(yes "1") | xargs -n1 -P4 sleep` 将运行 12 个 `sleep 1` 命令,4 个并行。该命令将需要 3 秒钟。 (4认同)
  • 可能值得注意的是 `-P 0` 将使用系统上的 cpu 数量 (3认同)

Ole*_*nge 57

使用GNU Parallel,您可以:

parallel script-to-run.sh input/ output/ {} ::: {0..99}
Run Code Online (Sandbox Code Playgroud)

在添加-P8如果你希望运行每个CPU核心一个作业.

相反xargs它会做正确的事情,即使输入包含空格',或'(不是这里的情况).它还确保不同作业的输出不会混合在一起,所以如果你使用输出你是保证你不会从两个不同的工作中获得半个职位.

GNU Parallel是一种通用的并行化程序,可以在同一台机器上或在您具有ssh访问权限的多台机器上轻松并行运行作业.

如果要在4个CPU上运行32个不同的作业,并行化的一种直接方法是在每个CPU上运行8个作业:

简单的调度

GNU Parallel会在完成后生成一个新进程 - 保持CPU处于活动状态,从而节省时间:

GNU并行调度

安装

如果没有为您的发行版打包GNU Parallel,您可以进行个人安装,不需要root访问权限.这样做可以在10秒内完成:

$ (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 3374ec53bacb199b245af2dda86df6c9
12345678 3374ec53 bacb199b 245af2dd a86df6c9
$ md5sum install.sh | grep 029a9ac06e8b5bc6052eac57b2c3c9ca
029a9ac0 6e8b5bc6 052eac57 b2c3c9ca
$ sha512sum install.sh | grep f517006d9897747bed8a4694b1acba1b
40f53af6 9e20dae5 713ba06c f517006d 9897747b ed8a4694 b1acba1b 1464beb4
60055629 3f2356f3 3e9c4e3c 76e3f3af a9db4b32 bd33322b 975696fc e6b23cfb
$ bash install.sh
Run Code Online (Sandbox Code Playgroud)

有关其他安装选项,请参阅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

浏览教程:http://www.gnu.org/software/parallel/parallel_tutorial.html

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

  • 这不回答问题,也没有指出为什么xargs无法达到同样的目的. (16认同)
  • downvote因为xarg对我来说完全如第二张图所示. (5认同)
  • 也许并非所有人都知道,这个答案是由GNU parallel的作者提供的。 (5认同)
  • @noonex您是否意识到并非每个人都使用您使用的xargs版本,并且-P不在所有版本的xargs中? (3认同)
  • 由于交互式提示弄乱了大多数脚本,该软件在第一次尝试时无法正确运行,因此被否决。 (2认同)

Pet*_*ost 14

下面是与 结合并行运行命令的示例find

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

-print0使用空字节而不是换行符终止文件名,因此我们可以-0在 xargs 中使用来防止带有空格的文件名被视为两个单独的参数。

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

-I %%表示用从标准输入读取的参数替换命令中出现的。

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

flac %是我们的命令,-I %之前的意味着这将变成flac foo.wav

另请参阅:xargs(1) 手册


Shu*_*pta 8

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

seq 1 500 | xargs -n 1 -P 8 script-to-run.sh input/ output/
Run Code Online (Sandbox Code Playgroud)