102

Is it possible to get the child process id from parent process id in shell script?

I have a file to execute using shell script, which leads to a new process process1 (parent process). This process1 has forked another process process2(child process). Using script, I'm able to get the pid of process1 using the command:

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

but i'm unable to fetch the pid of the child process.

TrueY
  • 7,360
  • 1
  • 41
  • 46
AlwaysALearner
  • 6,320
  • 15
  • 44
  • 59
  • 1
    Which child and which parent process are you talking about? By definition, a shell script is executed by a shell process! And why do you ask? Show your script please! – Basile Starynkevitch Jul 19 '13 at 10:29
  • I'll rephrase my question – AlwaysALearner Jul 19 '13 at 10:29
  • 5
    Wait... how does that `cat` command give you a PID ? – Miklos Aubert Jul 19 '13 at 10:36
  • 3
    It really seems that you are very confused! – Basile Starynkevitch Jul 19 '13 at 10:41
  • 1
    I second @BasileStarynkevitch : please show us your script, or at least the relevant part. – Miklos Aubert Jul 19 '13 at 10:45
  • And explain what exactly are *process1* and *process2* ... (what program are they each running). If you are coding these programs, add into them the functionality to write their pid in some file (like `/var/run/your-program.pid`...) – Basile Starynkevitch Jul 19 '13 at 10:59
  • 1
    @BasileStarynkevitch how to do this in c? how to get the process tree of a given pid in c language? – y_159 Aug 09 '20 at 09:16
  • 1
    @y_159: **The C11 standard [n1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf) or [this C reference](https://en.cppreference.com/w/c) don't even mention processes**. On Linux, use programmatically [proc(5)](https://man7.org/linux/man-pages/man5/proc.5.html) to get information about processes – Basile Starynkevitch Aug 09 '20 at 09:25
  • @BasileStarynkevitch so the only way to do this is to scan the whole proc filesystem and get the ppid of a process and then one can build a process tree? – y_159 Aug 09 '20 at 09:37
  • 2
    @y_159. Use [strace(1)](https://man7.org/linux/man-pages/man1/strace.1.html) on programs similar to yours (e.g. on `ps` or `top`) to find out what [syscalls(2)](https://man7.org/linux/man-pages/man2/syscalls.2.html) are involved, or take inspiration from existing projects -similar to yours- on [github](https://github.com/) or [gitlab](https://gitlab.com/) – Basile Starynkevitch Aug 09 '20 at 09:40

11 Answers11

178

Just use :

pgrep -P $your_process1_pid
Miklos Aubert
  • 4,405
  • 2
  • 24
  • 33
70

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

ps --ppid <pid of the parent>
Kent
  • 189,393
  • 32
  • 233
  • 301
27

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
Goofy
  • 431
  • 5
  • 7
16

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

where23
  • 483
  • 3
  • 9
15

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).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • From #bash on chat.freenode.net's greybot: The infamous "Advanced" Bash Scripting Guide should be avoided unless you know how to filter out the junk. It will teach you to write bugs, not scripts. In that light, the BashGuide was written: http://mywiki.wooledge.org/BashGuide; Just thought I'd mention it! – squirl Jan 26 '17 at 16:38
15

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/

y_159
  • 458
  • 3
  • 15
9
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
Dr.jacky
  • 3,341
  • 6
  • 53
  • 91
krishna
  • 99
  • 1
  • 1
4

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

Jack Ross
  • 41
  • 3
  • This is hacky, but it works, thanks. – Dave Jan 20 '22 at 20:08
  • Nice, I didn't know `\K` exists. I would have used `grep -oP '(?<=\()[^\)]+'`. More info about `\K`: https://stackoverflow.com/a/33573989/318765 – mgutt Mar 14 '23 at 09:50
2

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.

Dave
  • 727
  • 1
  • 9
  • 20
0

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,...
saaj
  • 23,253
  • 3
  • 104
  • 105
-3
#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;

}