如何从父进程获取子进程

是否可以从 shell 脚本中的父进程 ID 获取子进程 ID?

我有一个要使用 shell 脚本执行的文件,这将导致一个新的进程 过程1(父进程)。这个 过程1分叉了另一个进程 过程2(子进程)。通过使用脚本,我能够使用以下命令获得 过程1的 pid:

cat /path/of/file/to/be/executed

但我拿不到儿童程序的 PID。

219539 次浏览

Just use :

pgrep -P $your_process1_pid

The shell process is $$ since it is a special parameter

On Linux, the proc(5) filesystem gives a lot of information about processes. Perhaps pgrep(1) (which accesses /proc) might help too.

So try cat /proc/$$/status to get the status of the shell process.

Hence, its parent process id could be retrieved with e.g.

  parpid=$(awk '/PPid:/{print $2}' /proc/$$/status)

Then use $parpid in your script to refer to the parent process pid (the parent of the shell).

But I don't think you need it!

Read some Bash Guide (or with caution advanced bash scripting guide, which has mistakes) and advanced linux programming.

Notice that some server daemon processes (wich usually need to be unique) are explicitly writing their pid into /var/run, e.g. the  sshd server daemon is writing its pid into the textual file /var/run/sshd.pid). You may want to add such a feature into your own server-like programs (coded in C, C++, Ocaml, Go, Rust or some other compiled language).

I am not sure if I understand you correctly, does this help?

ps --ppid <pid of the parent>

I've written a script to get all child process pids of a parent process. Here is the code. Hope it will help.

function getcpid() {
cpids=`pgrep -P $1|xargs`
#    echo "cpids=$cpids"
for cpid in $cpids;
do
echo "$cpid"
getcpid $cpid
done
}


getcpid $1
ps -axf | grep parent_pid

Above command prints respective processes generated from parent_pid, hope it helps. +++++++++++++++++++++++++++++++++++++++++++

root@root:~/chk_prgrm/lp#


parent...18685


child... 18686




root@root:~/chk_prgrm/lp# ps axf | grep frk


18685 pts/45   R      0:11  |       \_ ./frk


18686 pts/45   R      0:11  |       |   \_ ./frk


18688 pts/45   S+     0:00  |       \_ grep frk
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>


int main()
{
// Create a child process
int pid = fork();


if (pid > 0)
{


int j=getpid();


printf("in parent process %d\n",j);
}
// Note that pid is 0 in child process
// and negative if fork() fails
else if (pid == 0)
{










int i=getppid();
printf("Before sleep %d\n",i);


sleep(5);
int k=getppid();


printf("in child process %d\n",k);
}


return 0;

}

To get the child process and thread, pstree -p PID. It also show the hierarchical tree

You can get the pids of all child processes of a given parent process <pid> by reading the /proc/<pid>/task/<tid>/children entry.

This file contain the pids of first level child processes. Recursively do this for all children pids.

For more information head over to https://lwn.net/Articles/475688/

For the case when the process tree of interest has more than 2 levels (e.g. Chromium spawns 4-level deep process tree), pgrep isn't of much use. As others have mentioned above, procfs files contain all the information about processes and one just needs to read them. I built a CLI tool called Procpath which does exactly this. It reads all /proc/N/stat files, represents the contents as a JSON tree and expose it to JSONPath queries.

To get all descendant process' comma-separated PIDs of a non-root process (for the root it's ..stat.pid) it's:

$ procpath query -d, "..children[?(@.stat.pid == 24243)]..pid"
24243,24259,24284,24289,24260,24262,24333,24337,24439,24570,24592,24606,...

You can print the PID of all child processes invoked by a parent process:

pstree -p <PARENT_PID> | grep -oP '\(\K[^\)]+'

This prints a list of pids for the main process and its children recursively

I used the following to gather the parent process and child processes of a specific process PID:

ps -p $PID --ppid $PID --forest | tail -n +2 | awk '{print$1}'

Note, this will not work to find child processes of child processes.