How to Get Process Id of Background Process

How to get process ID of background process?

You need to save the PID of the background process at the time you start it:

foo &
FOO_PID=$!
# do other stuff
kill $FOO_PID

You cannot use job control, since that is an interactive feature and tied to a controlling terminal. A script will not necessarily have a terminal attached at all so job control will not necessarily be available.

How to capture PID of a background process

actually pid are not allocated by bash but by the operating system, when a process is forked it is assigned a new pid, calling groovy .. & from bash process creates a new child process groovy which parent in bash process.

a bash function call doesn't create a new pid because it is run in the same process the same for a builtin command.

However because of the & after the function call this creates a new bash process (subshell), maybe one of the two & is not needed.

If you are interessed by the result of these processes you may need to wait for their execution this is what wait builtin does, a parallel execution could look to.

pids=()
for ... ; do
groovy ... &
pids+=( "$!" )
done

exit_codes=()
for pid in "${pid[@]}"; do
wait "$pid"
exit_codes+=( "$?" )
done

Capture pid when starting a background process in bash

The special variable $! contains the PID of the most recent job placed in the background:

$ sleep 4 &
$ sleep_pid=$!
$ echo $sleep_pid
4456

This is documented in Special Parameters of man bash

bash getting background process id gives parent pid

You already get the right information about the child process. Only in your case, ps doesn't know or want to show a proper COMMAND name for your chained sub-process you start in the background - what probably confused you.

Looks like this is the case with the chained commands (.. && ..., thus it has nothing to do with exit 1 could be also echo 5 etc.) where the process group leader name is showed as cmd name instead.

From the (ps man page)

`cmd | COMMAND`: simple name of executable

# Process state codes
`S`: interruptible sleep (waiting for an event to complete)
`+`: is in the foreground process group

See the S+ in your ps | grep output.

So, you can adapt your script a bit to confirm that you actually capture(d) the right information about the child process, like so:

cat <<"END"> z
#! /bin/bash

sleep 20 && exit 1 &
ret=$!

echo $ret

jobs -l

# display parent and child process info
# -j Jobs format
ps -j $$ $ret
END

Output of echo $ret:

30274

Output of jobs -l:

[1]+ 30274 Running                 sleep 20 && exit 1 &

Output of ps -j $$ $ret:

PID   PGID   SID   TTY    STAT    TIME COMMAND
30273 30273 21804 pts/0 S+ 0:00 /bin/bash ./z
30274 30273 21804 pts/0 S+ 0:00 /bin/bash ./z

Note that both the parent and child have the same PGID, whereas the pid 30274 of the child process displayed by jobs -l and ps ... matches.

Further, if you change sleep 20 && exit 1 & as bash -c 'sleep 20 && exit 1' & you would get a proper command name for the child this time, as follows (cf. output order above):

30384

[1]+ 30384 Running bash -c 'sleep 20 && exit 1' &

PID PGID SID TTY STAT TIME COMMAND
30383 30383 21804 pts/0 S+ 0:00 /bin/bash ./z
30384 30383 21804 pts/0 S+ 0:00 bash -c sleep 20 && exit 1

Last but not least, in your original version instead of ps $ret | grep $ret you could also try

pstree -s $ret

From pstree man page

-s: Show parent processes of the specified process.

Which will provide you with an output similar to that one below, which would also confirm that you get the right process info for sleep 20 && exit 1 &:

systemd───systemd───gnome-terminal-───bash───bash───sleep

Getting process id of background process in Perl

my $pid = fork;
if ($pid == 0) {
exec("sleep 2");
}
print "$pid\n";

Executing and get pid a background process in PHP on Windows

This will output the ProcessID after the task has been executed using wmic. You could then store this in a session or cookie to pass between pages.

$cmd = 'wmic process call create "C:/xampp/php/php.exe -f /path/to/htdocs/test.php" | find "ProcessId"';

$handle = popen("start /B ". $cmd, "r");

$read = fread($handle, 200); //Read the output

echo $read; //Store the info

pclose($handle); //Close

Output

ProcessId = 1000


Related Topics



Leave a reply



Submit