Marcus Thornton
Marcus Thornton

Reputation: 6193

How to control the process launched by a dispatcher in Unix/Linux

I have a dispatcher script (dispatcher.sh) like this:

for system in a b c
do
    cd /usr/xyz/$system/
    mkdir -p /usr/xyz/$system/time
    { time `./run_program.sh;wait` ;} > /usr/xyz/$system/time/time.log 2>&1 &
done

I wrote this to launch the run_program.sh in each folders and record the execution time. The task in each run_program.sh varies and some would fork child processes and grandchild processes.

  1. I would like to be able to stop/kill the each run_program.sh and their derivative child processes and grandchild processes.

  2. I also would like to know what child processes and grandchild processes of the each run_program is running. Is there any way I can check the fork tree?

Edit:

I don't have pstree on my system, so I have difficulty on visually know the pid relationship between parent process and offspring processes. If I kill the parent process, will offspring processes be killed? I currently use

ps -eo pid,pgid,args | awk '{if($2==PGID){print $1}}' PGID=pid| xargs kill -9

to kill the offspring processes of one parent process. Supposed that A forks B, and B forks C (A->B->C), and I kill process B, will C be automatically killed? How can I kill the process including A and B?

Upvotes: 0

Views: 841

Answers (2)

John B
John B

Reputation: 3646

You can get the process ID of the most recently executed background process by calling Bash builtin $!.

Then, you can kill -9 PID to kill all offspring of a process ID.

You could store the process IDs in an array and do something like kill them all upon signal interruption.

for system in a b c
do
    cd /usr/xyz/$system/
    mkdir -p /usr/xyz/$system/time
    { time `./run_program.sh;wait` ;} > /usr/xyz/$system/time/time.log 2>&1 &
    pids+=($!)
done
proc_kill () {
    kill -9 ${pids[@]}
}
trap proc_kill SIGINT

Upvotes: 0

isedev
isedev

Reputation: 19601

The following will be correct if these two assumptions hold:

  1. the run_program.sh script does not exit before any of its children / grandchildren
  2. the children/grandchildren do not become session leaders.

If that is case, then you can run run_program.sh in a new session so that it and all its children/grandchildren have the same process group ID.

You can then kill the script and all its children/grandchildren by using:

kill -9 -PID

where PID is the process ID of the run_program.sh script itself. Using -PID sends the signal to all members of the process group.

You can also list of children/grandchildren using a command like:

ps -eao pid,pgrp,args | awk '{if($2==PGRP){print $0}}' PGRP=PID

where PID is the process ID of the run_program.sh script itself.

You can modify your run_program.sh to write its PID (shell variable $$) to a file so you can easily retrieve it.

Upvotes: 0

Related Questions