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.
Just use :
pgrep -P $your_process1_pid
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
To get the child process and thread,
pstree -p PID.
It also show the hierarchical tree
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).
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/
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
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.
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,...
#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;
}
Related
I am building a nodejs commmand line application that starts several detached child processes. Some of them are express severs listening to at a specified port.
As I mentioned these processes are detached. How do i store information about these detached child processes like pid to kill them when the user wants.
I have tried writing them into a generic file which I later read to get the data.
Is there a better way?
You don't really have to keep track of all child process for terminating them. You can kill all the child process using their Process Group ID (PGID).
PGID=$(ps opgid= "$PID" | tr -d ' ')
kill -- -$PGID
You will get parent process Id (PID) by
ps aux | grep "process_name" | awk '{print $2}'
In your case the process name will be "node"
I had given a job in a remote server yesterday from my home. The command was
sh run.sh >& out &
The run.sh will excute a program (average.f) more than 1000 times recurssively.
Today, in my office, I found some mistake in my run.sh. So I would like to kill it.
I used top command, but it is not showing the run.sh. It is only showing average.f. So, once, I killed it with kill PID, it is again starting average.f with another PID and producing outputs.
ps -u is not showing either run.sh or average.f.
Can anybody please help me how to kill this job.
find your job id with the process or application name . example is given below - I am killing java process here
ps -aef|grep java
// the above command will give you pid, now fire below command to kill that job
kill -9 pid
// here pid is a number which you get from the first command
ps -ef | grep run.sh | grep -v grep | awk '{print $2}' | xargs kill -9
Use pstree(1) (probably as pstree -p) to list the process tree hierarchy, then kill(1) (first with -TERM, then with -QUIT, and if that does not work, at last with -KILL) your topmost shell process running run.sh (or else the few "higher" processes). Perhaps use killall(1) or pidof(1) (or pgrep(1) or pkill)
You might want to kill the process group, with a negative pid.
You should never at first kill -KILL a process (but only at last resort); some programs (e.g. database servers, sophisticated numerical computations with application checkpointing, ...) have installed a SIGTERM or SIGQUIT signal handler to clean up their mess and e.g. save some state (on the disk) in a sane way. If you kill -KILL them, they could leave the mess uncleaned (since SIGKILL cannot be caught, see signal(7)....)
BTW, you should use ps auxw to list all processes, read ps(1)
I need to track the process status ps axf during executable lifetime.
Let's say I have executable main.exec and want to store into a file all subprocess which are called during main.exec execution.
$ main.exec &
$ echo $! # and redirect every ps change for PID $! in a file.
strace - trace system calls and signals
$ main.exec &
$ strace -f -p $! -o child.txt
-f Trace child processes as they are created by currently traced processes as a result of the fork(2), vfork(2) and clone(2) system calls. Note that -p PID -f will attach all threads of process PID if it is multi-threaded, not only thread with thread_id = PID.
If you can't recompile and instrument main.exec, ps in a loop is a simple option that may work for you:
while true; do ps --ppid=<pid> --pid=<pid> -o pid,ppid,%cpu,... >> mytrace.txt; sleep 0.2; done
Then parse the output accordingly.
top may also work, and can run in batch mode but not sure if you can get it to dynamically monitor child processes like ps. Don't think so.
I have a bash process which calls another child process (mysqldump) for example. I need to determine the io usage of this child process. I tried cat /proc/self/io but values for io are connected only with the parent process. But I need the data for the child process. I can determine the pid of the child process and try view /proc/[pid of child]/io but when should I do that? If I do mysqldump and then /proc/[pid of child]/ioб /proc/[pid of child] won't exist after the finishing of the child process. Thanks!
You can probably use strace command as below to get that result.
strace -e trace=read,write -o ls.log ls
Here, strace will give the result for ls command. If you want to attach to particular process, use the -p pid option like
strace -e trace=read,write -o ls.log -p <child process PID>
More about Strace Command Here
How do I get the pid of a process as soon as it opens. Like lets say we run ./file.pl and then ./file2.pl As both these files will create a pid in /proc/ folder. How do I instantly know if the process has been created when the executable is run.
I have a file with all the commands ready to be run as soon as it gets the green signal that there is a new process in the /proc/ folder. How do I do that?
EDIT:
Please don't answer with a shell command. I don't need to know the pid. I need to develop a script which can know right away that we have a guest in the proc department
If you start the process via a shell, then start process in background:
./your_prog &
Get the pid:
echo $!
If the script give you the shell prompt back, you can do :
./your_prog
pidof -x your_prog
Tested OK with this perl script :
#!/usr/bin/perl
if (fork() == 0) {
sleep(600);
}
you need to
chmod +x your_prog
before...
Every process can get its own pid with the getpid(2) syscall. At process creation by fork(2) the parent process (e.g. some shell) gets the pid of the new child process. Read e.g. Advanced Linux Programming for more. And the kernel (not the program) is creating some subdirectory /proc/1234/ see proc(5) as soon as it creates the process of pid 1234.
Actually, /proc/ is not a real file system. It is just a pseudo file system giving a view on the state of the kernel and the entire Linux system.
Perl gives you its POSIX module to interface the syscalls. The getpid() syscall is interfaced using the $PID or $$ Perl variable.
The /proc/ pseudo filesystem is filled by the kernel. You could perhaps use inotify to follow change in /proc/ but this is very probably a bad idea.
Your question is not clear, we cannot understand what you really want to do and what you have tried.
Try out below shell script.(You may have to include changes in below script for your expected output)
#!/bin/bash
nr_proc_before=`ls -l /proc | wc -l`
ls /proc > proc_list_before
./any_executable &
nr_proc_after=`ls -l /proc | wc -l`
ls /proc > proc_list_after
nr_new=`expr $nr_proc_after - $nr_proc_before`
echo "$nr_new processes are created newly"
echo "new processes pids are :"
diff proc_list_after proc_list_before > new_pids
sed "1d" new_pids
if [ nr_new > 0 ] ; then
#trigger your file which has commands.
fi
Insted of any_execuatble you can replace with your things so that new processes will be created.
Note : This is not a script which monitors for new process. This sample of script may give you idea to solve your problem.
Please do reply for this answer, i can redefine my answer.