如何在Bash中并行运行命令?

4

这个问题之前已经被提出并且有很多答案,但我的需求比较特殊:

  • 我需要运行的进程都是长时间运行的进程,不会正常结束。
  • 我不想仅仅在后台运行它们,因为我需要看到它们的输出。
  • 如果其中任何一个进程退出,我希望其余的进程也能自动终止。
  • 如果我在主命令上使用Ctrl+C或其他信号,我希望杀死所有进程。

例如,使用& + wait无法满足最后一点。GNU parallel似乎相当复杂,并且可能能够做到这一点,但我找不到一个好的例子如何使用它。


请查看此处:https://stackoverflow.com/questions/41926123/kill-background-process-on-sigint。简而言之,您需要存储创建的子进程的pid,并在脚本接收到SIGINT时杀死它们。 - hek2mgl
我该如何使用GNU Parallel运行几个不同的命令?为了简化,假设我需要运行make consumemake projectmake run。我找不到如何使用parallel来实现这一点。另外,parallel --halt是什么鬼?--haltparallel --help中没有列出... - enumag
3个回答

3

经过一段时间的尝试,GNU parallel 看起来可以按照我所需工作。

将需要运行的脚本添加到 Makefile 中,以使其能够使用 make consumemake projectmake run 命令。

现在我可以像这样并行运行它们:

parallel --ungroup --halt now,success=1,fail=1 make ::: consume project run

通过使用--ungroup参数,我可以看到输出结果并且杀死进程也能正常工作。与我最初发布的帖子唯一的区别是当一个程序结束时其他程序没有被终止。但这并不重要。


你可以使用 make -j 命令并行运行 make 任务。 - John Kugelman
--halt now,success=1,fail=1 is not supported. You probably want --halt now,done=1 - Ole Tange
还可以考虑使用--linebuffer而不是--ungroup。这样,您可以确保从每个作业中获取完整的行,而不会看到半行的混合。 - Ole Tange
谢谢大家的建议!我下周会尝试实验一下这些。 - enumag
1
@OleTange 的 --halt now,done=1 不起作用:parallel: Error: --halt now 必须跟着 ,success 或者 ,fail. - enumag
您需要升级至>=20170422。 - Ole Tange

2
我需要运行的进程都是长时间运行的进程,不会正常结束。
我会使用您操作系统的 init 系统将它们作为系统服务运行。让一个专门管理长时间运行进程的系统来管理你的长时间运行进程。为什么要花费你的精力重新发明一个好的 init 系统已经拥有的所有功能,例如自动重启、日志管理和服务之间的依赖关系?
假设您的 init 系统是 systemd,这是现代 Red Hat 和 Debian 发行版所使用的。
我不想只是在后台运行它们,因为我需要看到它们的输出。
systemd 自动捕获 stdout 和 stderr,并将它们保存在其日志中。像 systemctl status <service>journalctl 这样的命令提供了许多查看和搜索日志数据的方法。您可以按严重级别或时间等许多元数据字段进行过滤。您可以查看单个服务的输出,也可以查看多个服务的组合输出。
如果其中任何一个进程退出,我希望其余进程也能自动停止。
systemd让你可以使用“BindsTo=”,“Requires=”或其他类似的选项来表达这个意思。有关详细信息,请参阅systemd.unit man page

如果我在运行它们的主命令上使用Ctrl+C或其他信号,我想杀死所有进程。

你可以使用systemctl stop <service>停止服务。它会停止指定的服务及其依赖项。
要了解systemd可以为您提供的所有功能,请查看其手册:

0

你可以使用 xargs -P0


-P max-procs, --max-procs=max-procs 一次最多运行max-procs个进程;默认值为1。如果max-procs为0,则xargs将尽可能地运行尽可能多的进程。使用-n选项或-L选项与-P一起使用;否则只有一个exec将被执行的机会。在xargs运行时,您可以向其进程发送SIGUSR1信号以增加同时运行的命令数,或者发送SIGUSR2以减少数量。您不能将其增加到超过实现定义的限制(该限制显示在--show-limits中)。您不能将其减少到1以下。xargs永远不会终止其命令;当要求减少时,它只是等待超过一个现有命令终止后再启动另一个。


1
虽然出于好意,但如果没有接近 O.P. 问题解决方案的引用 man page,实际上并没有太大帮助。其他人可能会投反对票。继续发布,但请提供您的经验或解决方案!祝你好运。 - shellter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接