LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   How to wait for the process and know if the exit code of the sub process (https://www.linuxquestions.org/questions/linux-general-1/how-to-wait-for-the-process-and-know-if-the-exit-code-of-the-sub-process-661009/)

williamhomanchun 08-06-2008 08:20 PM

How to wait for the process and know if the exit code of the sub process
 
I am trying to find out in shell how to wait for the background process to finish before continous, and how to know the exit code for the background process which have finish.

Basically, if I do the following, I can wait for the background processes
sleep, but the problem is that, if I kill one of the sleep process, the
wait command do not return the kill status of the background process, it
always return 0, but I want the script to return the exit code as fail if
one of the subprocess fail.

#!/bin/csh -f
sleep 10 &
sleep 30 &
wait

If I do the following in bash shell, it only wait for one job and return
failing of the job in only one background process, I need to check for 2 process.

#!/bin/bash
sleep 10 &
wait %1

How could I wait for 2 background process and return their exit code ?

Mr. C. 08-06-2008 08:53 PM

See wait in man bash:
Quote:

wait [n ...]
Wait for each specified process and return its termination sta-
tus. Each n may be a process ID or a job specification; if a
job spec is given, all processes in that job's pipeline are
waited for. If n is not given, all currently active child pro-
cesses are waited for, and the return status is zero. If n
specifies a non-existent process or job, the return status is
127. Otherwise, the return status is the exit status of the
last process or job waited for.

williamhomanchun 08-07-2008 08:17 PM

Thanks a lot, it seem like it is work.

BTW, does it have any way to find all the exit code of the all background job.
i.e

command1 &
command2 &
command3 &

Also, how to know the process id of all the background job, since I want to kill
all the background job whenever there is a SIGTERM (ctrl-C)

#!/bin/bash -f

trap_proc () {
kill <all process> <--- How to find all the background job process id
exit 1
}

command1 &
command2 &
trap trap_proc 2 15
wait %1 %2

custangro 08-07-2008 08:33 PM

Quote:

Originally Posted by williamhomanchun (Post 3240378)
Thanks a lot, it seem like it is work.

BTW, does it have any way to find all the exit code of the all background job.
i.e

command1 &
command2 &
command3 &

Also, how to know the process id of all the background job, since I want to kill
all the background job whenever there is a SIGTERM (ctrl-C)

#!/bin/bash -f

trap_proc () {
kill <all process> <--- How to find all the background job process id
exit 1
}

command1 &
command2 &
trap trap_proc 2 15
wait %1 %2

You can do a for loop...
Code:

for cmdpid in $(pgrep cmd)
do
  kill ${cmdpid}
done

...Or you can use pkill

Mr. C. 08-07-2008 10:20 PM

$! is the PID of the most recently backgrounded proccess. Capture and save this value after you start each job in the background:

somejob1 &
bgpid1=$!
somejob2 &
bgpid2=$!

Use an array instead of unique variables each time, or whatever storage method is convenient for your needs.

williamhomanchun 08-08-2008 05:55 PM

Now I meet another problem, when I kill the pid of the child process. The child process also start off some other process. It just happen when I kill the top level child process alone, all its child process under are not kill. since I do not use "exec" command to run the child process, its child child process give new pid.

Does it have a way know all the child process under the parent process, and kill them all.
Do I need to do a while loop my self to search for all the child process ?

myname 27730 27728 0 09:17:56 pts/193 0:00 childprocess1
myname 27731 27728 0 09:17:56 pts/193 0:00 childprocess2
myname 27732 27730 0 09:17:56 pts/193 0:00 child-childproess1
myname 27733 27731 0 09:17:56 pts/193 0:00 child-childproess2
myname 27759 27733 0 09:17:57 pts/193 0:00 child-child-childproess1
myname 29268 27761 0 09:19:20 pts/193 0:00 child-child-childproess2
myname 29269 29268 0 09:19:20 pts/193 0:00 child-child-child-chiledprocess2



find_child_process () {
childpids=`pgrep -P $1`
echo "pgrep $childpids"
for childpid in $childpids
do
allpids="$allpids $childpid"
echo addprocess $allpids
if [ "$childpid" != "" ]
then
echo " - call find_child $childpid"
find_child_process $childpid
fi
done
}

Mr. C. 08-08-2008 06:09 PM

Use a negative PID to kill all processes within the process group.

See the PGID column in ps.

williamhomanchun 08-08-2008 07:10 PM

> Use a negative PID to kill all processes within the process group.
> See the PGID column in ps.

Can you explain how to use PGID to kill all the process ?
In my version of ps, I don't have

> ps -fu myname | grep -v tcsh | sort +4 | less
UID PID PPID C STIME TTY TIME CMD
myname 29065 1 0 09:59:55 ? 0:00 /bin/sh /opt/sfw/bin/thunderbird
:

Mr. C. 08-08-2008 07:22 PM

add -Opgid to your ps command line, as in:

ps -xa -Opgid # that's the letter O, not zero.

kill -TERM PID # kills process id PID.
kill -TERM -PID # kills the process group that PID is in.

williamhomanchun 08-11-2008 02:17 PM

Thanks a lot it really work. Now, when I have a lot of bg job, I don't need to look at ps one byone, and kill them one by one.

But I have one questions, when the shell will start a new pgid ?
Is that anytime when we type in a shell with interactive shell window, it will be given a new gpid ?

If there is a script calling this script RUNFILE, when the process of RUNFILE is being killed,
since the trap subroutine try to kill the pgid,it will kill the parent process as well ?


RUNFILE
=========
#!/bin/bash -f

trap_proc () {
pgid=`ps -p $$ -o pgid="" | awk '{print $1}'`
kill -9 -$pgid
exit 1
}

<Command1> &
bgpid1=$!
<Command2> &
bgpid2=$!
trap trap_proc 2 15
wait $bgpid1 $bgpid2


If it is the case, does I have a method to start a new pgid when I call on a new script, for example, this RUNFILE. or it will always following the parent pgid.

Mr. C. 08-11-2008 02:32 PM

man bash, search for

process.*group


All times are GMT -5. The time now is 01:32 PM.