This is not possible in general. It may be possible in your specific case.
Just after running a background command, the process ID is discoverable from the parent. If you run a foreground command (a child of the master program), and that command in turn runs a background command (a grandchild of the master program), the master program has no direct visibility on its grandchild: all it knows is that it's run a child process, which has now exited.
The kernel keeps track of child→parent process relationships. You can run ps -o ppid= -p $pid
to see the process ID of the parent process of the process whose ID is $pid
. The kernel does not keep track of a process's grandparent. Furthermore, if the parent dies, the process is adopted by init (process number 1), so its parent process ID will be 1 from that point on.
There are several other process attributes that are inherited and that you might try to keep track of. However the grandchild can divorce from any of these attributes. If the grandchild is intended to run as a daemon, it probably will attempt to isolate itself as much as possible (either from the intermediate child or from the grandchild itself), so that it isn't tied to your interactive session and doesn't risk getting caught in anything happening to this session.
You can look for processes in the same process group as the current process (ps -o pgid=
)). This will catch any other process started within the same process group, but conversely miss the grandchild if it runs in its own process group due to a call to setpgid
or setpgrp
in the child or the grandchild, which daemons do.
You can look for processes in the same session ID as the current process (ps -o sid=
)). This will catch any other process started within the same session ID, but conversely miss the grandchild if it runs in its own session due to a call to setsid
in the child or the grandchild, which daemons do.
You can open a temporary file and look for processes that have this file open (`fuser "$tmpfile"). This is more reliable because it will only catch processes started from the part of the master process that had this file open, it won't catch whatever other components of the master process might have done. However like other solutions it will miss the grandchild if it or the intermediate child closed the file descriptors it didn't use, which daemons do.
Most daemons have a command line option to stay in the foreground. You can then run daemon --foreground & daemon_pid=$!
, and it's up to you to take precautions to avoid the daemon being caught in the session exit (nohup daemon --foreground </dev/null >daemon.log 2>&1 &
is a good start).