英文:
Bash - get all the children of a process even the ended ones
问题
在Bash脚本中,我有一个名为A的进程,它运行一个很快结束的进程B,然后进程B又会运行其他进程。我想获取A的所有后代进程,但就好像A没有任何子进程一样。我尝试使用:
pgrep -P <A的PID>
和
ps -o pid= --ppid <A的PID>
但我没有获得子进程。
我如何能够获取A的所有子进程,即使是已经结束的子进程,以及所有后代进程?
英文:
In a Bash script I have a process A that runs a process B that ends very quickly and that, in turns, runs itself other processes. I would like to get all the descendants of A, but it's like if A did not have any children. I tried to use:
pgrep -P <A's PID>
and
ps -o pid= --ppid <A's PID>
but I get no children.
How could I get all the children of A, even the ended ones, and all it's descendants?
答案1
得分: 2
这个简短的Bash程序演示了实现你想要的一种可能方式:
#! /bin/bash -p
set -o monitor
((sleep 3 & sleep 4 &); sleep 5) &
pgid=$!
sleep 1 # 允许所有后台进程启动的时间
pgrep -g "$pgid" -a
wait
set -o monitor
打开了作业控制。作业控制不会在非交互式 shell 中默认启用。启用作业控制的一个效果是所有后台进程都会有自己的进程组。子后台进程及其所有后代都成为同一个进程组的成员。((sleep 3 & sleep 4 &); sleep 5) &
启动一个后台进程。该进程创建一个子进程,在后台运行sleep 3
和sleep 4
,然后退出。这意味着sleep 3
和sleep 4
变成孤儿进程。但它们保留与顶层后台进程相同的进程组ID。pgid=$!
存储了顶层后台进程的PID。这也是新进程组的进程组ID。pgrep -g "$pgid" -a
列出了顶层后台进程的进程组中的进程的详细信息。在这种情况下,它列出了.../bash ...
(由最外层的(...)
创建的 shell),sleep 3
,sleep 4
和sleep 5
。- 由内部的
(...)
创建的子进程已经退出,并由其父shell等待,因此没有留下它的记录(除非可能某种形式的进程审计处于活动状态)。它不会出现在pgrep
的输出中。
英文:
This short Bash program illustrates one possible way of doing what you want:
#! /bin/bash -p
set -o monitor
((sleep 3 & sleep 4 &); sleep 5) &
pgid=$!
sleep 1 # Allow time for all descendant processes to start
pgrep -g "$pgid" -a
wait
set -o monitor
turns on job control for the program. Job control is not enabled by default for non-interactive shells. One effect of enabling job control is that all background processes get their own process groups. A child background process and all if its descendants all become members of the same process group.((sleep 3 & sleep 4 &); sleep 5) &
starts a background process. That process creates a child process that runssleep 3
andsleep 4
in the background and exits. That means thatsleep 3
andsleep 4
become orphan processes. However, they retain the same process group id as the top-level background process.pgid=$!
stores the PID of the top-level background process. It is also the process group ID for the new process group.pgrep -g "$pgid" -a
lists details of the processes in the process group of the top-level background process. In this case it lists.../bash ...
(the shell created by the outermost(...)
),sleep 3
,sleep 4
, andsleep 5
.- The child process created by the inner
(...)
has exited and been waited for by its parent shell, so there is no record of it left (unless maybe some form of process auditing is active). It does not appear in thepgrep
output.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论