如何从bash脚本中并行运行多个程序?

34 浏览
0 Comments

如何从bash脚本中并行运行多个程序?

我正在尝试编写一个能够同时运行多个程序的.sh文件。\n我尝试了以下代码:\n

prog1
prog2

\n但是这样会先运行prog1,然后等待prog1结束后再开始运行prog2...\n那么我该如何并行运行它们呢?

0
0 Comments

如何在Bash脚本中并行运行多个程序?

如果你想要能够轻松地运行和终止多个进程,并且使用ctrl-c,这是我最喜欢的方法:在一个(...)子shell中生成多个后台进程,并捕获SIGINT信号执行kill 0命令,它将终止子shell组中的所有进程:

(trap 'kill 0' SIGINT; prog1 & prog2 & prog3)

你可以创建复杂的进程执行结构,一切都将在单个ctrl-c下关闭(只需确保最后一个进程在前台运行,即prog1.3后面不要加&):

(trap 'kill 0' SIGINT; prog1.1 && prog1.2 & (prog2.1 | prog2.2 || prog2.3) & prog1.3)

如果最后一个命令可能会提前退出,并且你希望保持其他所有进程继续运行,请将wait作为最后一个命令添加。在下面的示例中,sleep 2会先退出,导致在它完成之前终止sleep 4;添加wait命令可以使两者都运行完成:

(trap 'kill 0' SIGINT; sleep 4 & sleep 2 & wait)

这是迄今为止最好的答案。

kill 0是什么意思?它是指子shell本身的PID 0吗?

是的,kill命令将0解释为“当前进程组中的所有进程都被发送信号”。man页面中包含了这个描述。

太棒了,运行得很好。这是一个很好的示例,说明了子shell的用途。

我必须使用trap 'kill 0' INT;代替SIGINT

我使用了(trap 'kill 0' SIGINT EXIT; blabla),因为它更可靠(当错误发生时终止所有守护进程)。

谢谢!提醒一下:我需要为每个命令的输出使用grep,所以我发现可以简单地使用(trap 'kill 0' SIGINT; prog1 & prog2) | grep XXX而不是(trap 'kill 0' SIGINT; (prog1 | grep XXX) & (prog2 | grep XXX))

只有在最后一个命令(前台命令)也是最后退出时,才有效。否则整个过程会过早退出。

(trap 'kill 0' SIGINT; prog1 & prog2 & prog3 & wait)可以确保所有程序都完成。

这在WSL2上实际可行!

Ingo Bürk的评论似乎是正确的。例如,(trap 'kill 0' SIGINT; (sleep 4; echo Hello) & (sleep 2 ; echo World))的结果是:等待两秒钟,打印"World",剩余的进程在后台(即,你又有了一个活动的Shell提示符),然后再等待两秒钟,打印"Hello"。

我已经更新了答案,建议使用wait作为最后一个命令。感谢Ingo Bürk、orion elenzil和jakeonfire的建议。

这是一个很好的答案,但我建议将更新后的wait版本放在前面,并将其作为主要解决方案。99%的情况下,用户都会期望这样的结果。

0
0 Comments

如何在bash脚本中并行运行多个程序?

要并行运行多个程序,可以使用以下命令:

prog1 &
prog2 &

如果需要脚本等待这些程序运行结束,可以在需要等待的位置添加以下命令:

wait

不要忘记使用wait命令!在bash中,可以等待脚本的子进程。

另一个选项是使用nohup命令,防止程序在shell挂断时被终止。

是的,这种方法也适用于并行运行三个或更多个程序。

也许是一个愚蠢的问题,但如果我想运行prog1 | something & prog2 | another &,会发生什么?我相信这不会起作用。

它完全可以正常工作;为什么你认为它不会起作用?

有没有办法只列出从当前bash终端创建/运行的进程?

这个问题可能值得提问,但简短的回答是你可以运行jobs命令来查看从当前shell放入后台的进程。

当prog1不返回光标控制权时,也就是在一个终端上一个程序占用了,所以prog2将需要一个新的终端,这种情况怎么办?

我不确定你的意思。显然,在同一个终端中不能同时运行多个需要完全控制终端的程序 - 但这不是问题的要求 - 它询问的是如何从同一个脚本中同时运行大量程序 🙂

prog1prog2都在后台运行吗?

如果它们两个后面都有&,那么是的,它们都在后台运行。

如果有人能展示一下如何使用wait命令以及同时运行的prog1和prog2,那将很棒。不是交互式的,可以通过许多更简单的方式来实现,比如只运行第二个终端...我想wait命令可以神奇地跟踪脚本中所有正在后台运行的进程?如何确保如果其中一个程序以!= 0退出,我的脚本会终止?

0
0 Comments

问题的出现原因:在bash脚本中如何同时运行多个程序。

解决方法:使用以下命令:

prog1 & prog2 && fg

这将实现以下功能:

1. 启动prog1

2. 将prog1发送到后台,但保持输出。

3. 启动prog2,并将其保持在前台,以便可以使用ctrl-c关闭。

4. 当关闭prog2时,会返回到prog1的前台,以便也可以使用ctrl-c关闭。

如果想要在prog2终止时轻松终止prog1,可以尝试以下命令:node srv.js & cucumberjs

也可以尝试稍作修改:prog1 & prog2 ; fg。这适用于同时运行多个SSH隧道。

如果希望在prog2无法立即运行时,自动返回到prog1的前台,那么上述方法是可行的。

在SSH的shell中,如果执行类似命令,将很难终止prog1。即使按下ctrl-c,也不起作用。即使终止整个终端,prog1仍然在运行。

一种同时终止两个进程的方法是:prog1 & prog2 && kill $!

可以使用以下命令一次停止两个命令:prog1 & pid1="$!" ; prog2 ; kill $pid1

这对我起作用。在第一次按下ctrl-c后,prog1将回到前台:prog1 & prog2 && fg; fg

需要注意的是,在shell脚本中不能使用fg命令。会显示"fg: no job control"。这是因为脚本不是交互式的shell。

0