如何获取脚本生成的所有子进程的列表

如何获取脚本生成的所有子进程的列表

语境:

用户向我提供他们要运行的自定义脚本。这些脚本可以是任何类型的脚本,例如用于启动多个 GUI 程序、后端服务的脚本。我无法控制脚本的编写方式。这些脚本可以是阻塞类型,即执行等待所有子进程(按顺序运行的程序)退出

#exaple of blocking script
echo "START"
first_program 
second_program 
echo "DONE"

或非阻塞类型,即在后台分叉子进程并退出

#example of non-blocking script
echo "START"
first_program &
second_program &
echo "DONE"

我想要实现什么?

用户提供的脚本可以是上述两种类型中的任何一种,也可以是两者的混合。我的工作是运行脚本并等待它启动的所有进程退出,然后关闭节点。如果它是阻塞类型,情况很简单,即获取脚本执行进程的 PID 并等到 ps -ef|grep -ef PID 没有更多条目。非阻塞脚本给我带来了麻烦

有没有办法获取脚本执行生成的所有子进程的 PID 列表?如能提供任何指点或提示,我将不胜感激

答案1

为了直接回答你的问题,命令

jobs -p

为您提供所有子进程的列表。

替代方案 #1

但在您的情况下,使用wait不带任何参数的命令可能会更容易:

first_program &
second_program &
wait

这将等到全部子进程已完成。

替代方案 #2

另一种方法是使用$!获取最后一个程序的 PID 并可能累积在变量中,如下所示:

pids=""
first_program &
pids="$pids $!"
second_program &
pids="$pids $!"

然后使用 wait (如果您只想等待子进程的子集):

wait $pids

替代方案 #3

或者,如果您只想等到任何过程已完成,您可以使用

wait -n $pids

奖金信息

如果您希望您的 bash 脚本中的一个信号也关闭您的子进程,您将需要使用类似这样的方式传播信号(在启动任何进程之前,将其放在顶部的某个地方):

trap 'kill $(jobs -p)' SIGINT SIGTERM EXIT

答案2

谢谢大家的回复..我在 stackoverflow 上找到了解决方案

您可以使用 wait 等待 userscript 启动的所有后台进程完成。由于 wait 仅适用于当前 shell 的子进程,因此您需要获取它们的脚本,而不是将其作为单独的进程运行。

(源用户脚本;等待)

在显式子 shell 中获取脚本应该足够接近地模拟启动新进程。如果没有,您也可以将子 shell 置于后台,这会强制启动新进程,然后等待它完成。

(源用户脚本;等待)&等待

以下是@chepner 原始答案的链接:https://stackoverflow.com/questions/18663196/how-to-get-list-of-all-child-process-spawned-by-a-script/18663969?noredirect=1#18663969

相关内容