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

时间:2019-05-30 08:10:55

标签: bash shell

这已经被问过了,有很多答案,但是我的需求更加具体:

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

例如,使用& + wait不能满足最后一点。 GNU并行似乎很复杂,也许可以做到这一点,但我找不到如何使用它的好例子。

3 个答案:

答案 0 :(得分:3)

摆弄GNU parallel一段时间后,这似乎可以按照我的需要工作。

将我需要运行的脚本添加到我的Makefile中,以便可以以make consumemake projectmake run的形式使用。

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

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

使用--ungroup,我可以看到输出,并且杀死也似乎按预期进行。与我最初的帖子唯一的区别是,当其中一个程序结束时,其他程序不会被杀死。但这并不重要。

答案 1 :(得分:2)

  

我需要运行的进程都是长时间运行的进程(通常不会终止)。

我将使用您操作系统的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可以为您做的所有事情,请仔细阅读其手册:

答案 2 :(得分:0)

您可以使用xargs -P0


-P max-procs,--max-procs = max-procs               一次运行max-procs进程;默认值为1。如果max-procs为0,则xargs一次将运行尽可能多的进程。使用-n选项或               带-P的-L选项;否则,只有一名高管会被执行。 xargs运行时,可以向其进程发送SIGUSR1信号以增加               要同时运行的命令数,或者使用SIGUSR2减少命令数。您不能将其增加到实现定义的限制(即               以--show-limits显示)。您不能将其降低到1以下。xargs永远不会终止其命令;当要求减少时,它仅等待一个以上               在启动另一个命令之前先终止命令。