简体   繁体   中英

Bash: Get child process name

I'm new with bash. I'm have this little code:
bash.sh

./mama

mama.cpp

#include <stdlib.h>
int main()
{
  system("./shvili");
  while(1){}
}

shvili.cpp

int main()
{
  while(1){}
}

As it shows me mama is parent of shvili process. I have situation like this where I don't know exactly the name of child process. So my question is, How can I get the PID of child process from c++?(It would be more comfortable for me to get the name of process).

A way to at least check via bash in case "situation like this where I don't know exactly the name of child process" but knows the name of the parent process assumed to be unique, one can use in bash based on ps , grep , sed (to remove leading space for smaller pids), tr (to squeeze multiple consecuting spaces into one), and cut :

$> cat foo_bar.sh 
#! /bin/bash
sleep 120

$> ./foo_bar.sh &
[1] 89239

$> ps -eo pid,ppid,args|grep -e " $(ps -eo pid,args| grep foo_bar.sh| grep -v grep| sed s/^\ //g |cut -f 1 -d ' ') "|grep -v foo_bar.sh| sed s/^\ //g | tr -s ' ' | cut -f 1,3 -d ' '
89241 sleep

Thus the unique name of the parent process is used to determine the parent pid:

$> ps -eo pid,args| grep foo_bar.sh| grep -v grep| sed s/^\ //g |cut -f 1 -d ' '
89239

This evaluated in a sub process ( $(...) ) is used to grep the correct line from another ps call to determine the seeked pid of child and name (without additional arguments and without prior knowledge of the childs name.

Note - as usual in bash some spaces are important - the added space at the end of the search pattern:

... grep " $(ps -eo pid,args| grep foo_bar.sh| grep -v grep| cut -f 1 -d ' ') " ...

This helps avoid false positives, like when a parent pid is 123, without padding with spaces this would match many pids that contain these digits like 1234, 12345, 1123, ...

Update (reacting on comment): In case parent process is a_mama (forking off a_shvili sub process) and it is the only process with that name on the machine, then the following should work:

$> p_proc="a_mama"
$> ps -eo pid,ppid,args|grep -e " $(ps -eo pid,args| grep ${p_proc}| grep -v grep| sed s/^\ //g | cut -f 1 -d ' ') "|grep -v ${p_proc}| sed s/^\ //g | tr -s ' ' | cut -f 1,3 -d ' '
12346 a_shvili

you can try using pidof to get the pid of a particular process.

Example

char line[LEN];
FILE *cmd = popen("pidof...", "r");

fgets(line, LEN, cmd);
pid_t pid = strtoul(line, NULL, 10);

pclose(cmd);

You do know the name of the child process it is shvili , how can you start it and not know its name.

If you with to know the PID of the child, then do not use system . system is not a well behaved procedure, do not use it.

Instead use fork and exec :

In parent do:

#include <unistd.h>

int child_pid = fork();
if (child_pid == -1) {
   //fork failed do something about it
} else if (child_pid == 0) {
   //this runs for child
   execl("shvili", NULL);
   //if you get here then exec errored
} else {
   //This runs for parent
   //child_pid has child pid
   //Add parent code hear.
   wait(…);
}

Explanation:

  • the first branch of the ifs runs if fork errors.
  • else
    • In 2 separate processes:
    • the second branch runs for the child.
    • and the third branch runs for the parent.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM