一个命令的所有子进程的PID

4
在bash脚本中,我想要启动一个前台进程,并打印出所有作为该进程子进程启动的进程名称和PID列表。例如,假设我有以下脚本,但我只能修改第一个脚本:
A.sh:
#!/bin/bash
B.sh

B.sh:

#!/bin/bash
C.sh

C.sh:

#!/bin/bash
echo "Running C.sh"

不修改B.sh、C.sh或echo命令,并且不在后台启动任何子进程,我希望A.sh打印如下内容:

B.sh 1208
C.sh 1210
echo 1211

A.sh能否fork一个进程来记录这些信息,同时子进程在A.sh前台运行?

2个回答

4
更新:在我的回答下面的评论中,事实证明:
“我需要观察一段时间内所有子进程的创建。鉴于此,过滤以隔离我的子树将不困难。”
...是问题背后的意图,这是为了调试目的。
在这种情况下,我建议像这样使用 strace
strace -f command

-f选项可以递归跟踪子进程。由于fork和exec调用需要系统调用,strace将列出任何子进程的创建及其pid。


原始答案:

你可以使用pgrep来实现:

run_process &
pid=${!}
pgrep --parent "${pid}"
wait # wait for run_process to finish

顺便说一下,你可能想使用pstree命令,它很好用:

run_process &
pid=${!}
pstree -p "${pid}"
wait # wait for run_process to finish

无论如何,你需要安装pstree

正如我在问题中提到的,我不想在后台启动任何进程。& 运算符会在后台启动一个进程。有没有办法在前台运行即将运行的命令时使用 pstree 呢? - Byron Hawkins
应该怎么做呢?只能有一个前台进程。但是在后台启动进程有什么问题吗?我在我的答案中添加了wait命令。这基本上对你来说应该可以很好地工作。除了一个问题,你如何确保在询问时进程已经启动了它的子进程? - hek2mgl
分叉只会给我B.sh的PID。即使在B.sh运行时不断轮询pstree,我仍然可能会错过一些子进程。我需要观察一段时间内所有子进程的创建情况。鉴于此,过滤以隔离我的子树将不是困难的。 - Byron Hawkins
strace可以工作了!你能否更新你的答案,这样我就可以标记它吗?谢谢。 - Byron Hawkins
很高兴听到这个消息! :) 我更新了我的答案...(附注:我建议您重新以反映实际问题的方式重写您的问题。这可以在最后两个句子中完成(只需删除其余部分)。问题本身很有趣,但问题有点模糊) - hek2mgl
显示剩余2条评论

0

您可以尝试使用 A.sh 来完成这个任务。

#!/usr/bin/env bash
./B.sh &
b_PID=$!
./C.sh &
c_PID=$!

echo "B.sh $b_PID"
echo "C.sh $c_PID"

输出结果将类似于这样

B.sh 22802
C.sh 22803
Running C.sh

正如我在问题中提到的,我不想在后台启动任何进程。& 运算符会在后台启动一个进程,这是我特别不想要的。 - Byron Hawkins
@ByronHawkins 如果你不将 B.sh 启动到后台,AB.sh 完成之前什么都做不了,更别说你想要的事情了。 - chepner
1
不可能做到你所要求的,拜伦。这个过程需要被分叉。 - NinjaGaiden
可以分叉一个监视器进程来记录执行过程中的子进程树,这样做是可以的。但我不想分叉作业本身。 - Byron Hawkins

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