background processing in BASH

I have script 3 scripts
1 parent
2 children
child1
child2

In the code below the 2 child processes fire almost Instantaneously in the background, Is that possible to know the status of pass/fail of each process "as it happens" ?

In the present scenario although Child2 failed first ( exit 1 ) the status is not displayed until Child1 is complete.

I would really apprecitate your help.

Mother Process:

 #!/bin/bash
 
 echo -e " Parent continued process 1"
 echo -e " Parent continued process 2"
 echo -e " ** Kicking off a child process C1** "
 ./child1 &
 t1=$!
 echo -e " Parent continued process 3"
 echo -e " Parent continued process 4"
 echo -e " ** Kicking off a child process C2** "
 ./child2 &
 t2=$!
 
  wait $t1
  if [ $? -ne 0 ]
  then
    echo " Child Process C1 failed !!! "
  fi
 
  wait $t2
  if [ $? -ne 0 ]
  then
    echo " Child Process C2 failed !!! "
  fi
 
 exit 0

Child1

 
 #!/bin/bash
 echo -e " in child process 1 "
 sleep 2
 echo -e " in child process 2 "
 sleep 2
 echo -e " in child process 3 "
 sleep 7
 exit 0 # success

Child 2

  #!/bin/bash
 echo -e " in child process 4"
 echo -e " in child process 5"
 echo -e " in child process 6"
 exit 1 # failed

Thanks,
SSR.:b:

That's because you are waiting for the first child before anything else. You can try plain "wait", but that doesn't return until ALL children have completed.

What you can do is set up a wait-loop, and then set up a signal handler to call "jobs" or check on the specific status of any jobs; and set up an alarm-like thingy to wake up the signal handler. The wait call then gets pre-empted. So for instance, something like this (untested) in bash might work:

job1 & 
job2 &

# turn off immeidate job notification
set +b

# trap USR1 signal with null action
trap test USR1

# set up an alarm
{ sleep 1; kill -USR1 $$; } &
# disown so it does not show up in job table
# (with other shells, this can be emulated by starting it as its own session leader)
disown $!   # acts differently in ksh

# keep waiting till all jobs are complete
while ! wait; do 
   DONE=`jobs -n | sed -n '/ Done / s/^\[\([0-9]*\)\].*/\1/p'`
   if [ -n "$DONE" ]; then 
      echo -n "Jobs $DONE were completed at " 
      date
   fi
   # restart timer
   { sleep 1; kill -USR1 $$ ; } &
   disown $!
done

When wait exits with 0, there are no remaining background tasks, and the loop terminates. If you don't have bash, but have "setsid", you can effectively disown a process that way.

Getting an error

./p2: line 25: kill: (24255) - No such process

Are you using bash?

Have you tried "set -x" at the top of the code to see where execution fails? (Line 25 doesn't really help).

here is the o/p after I added set -x

+ ./child1
+ ./child2
+ set +b
+ trap test USR1
+ sleep 1
+ disown 24540
+ wait
in child process 1 child1
in child process 4 child2
in child process 5 child2
in child process 6 child2
+ kill -USR1 24534
++ test
++ jobs -n
++ sed -n '/ Done / s/^\[\([0-9]*\)\]./\1/p'
+ DONE=
+ '[' -n '' ']'
+ sleep 1
+ disown 25575
+ wait
in child process 2 child1
+ kill -USR1 24534
++ test
++ jobs -n
++ sed -n '/ Done / s/^\[\([0-9]*\)\].
/\1/p'
+ DONE=
+ '[' -n '' ']'
+ sleep 1
+ disown 26616
+ wait
+ kill -USR1 24534
++ test
++ jobs -n
++ sed -n '/ Done / s/^\[\([0-9]*\)\]./\1/p'
+ DONE=
+ '[' -n '' ']'
+ sleep 1
+ disown 27658
+ wait
in child process 3 child1
+ kill -USR1 24534
++ test
++ jobs -n
++ sed -n '/ Done / s/^\[\([0-9]*\)\].
/\1/p'
+ DONE=
+ '[' -n '' ']'
+ sleep 1
+ disown 28694
+ wait
+ kill -USR1 24534
++ test
++ jobs -n
++ sed -n '/ Done / s/^\[\([0-9]*\)\]./\1/p'
+ DONE=
+ '[' -n '' ']'
+ sleep 1
+ disown 29744
+ wait
+ kill -USR1 24534
++ test
++ sed -n '/ Done / s/^\[\([0-9]*\)\].
/\1/p'
++ jobs -n
+ DONE=
+ '[' -n '' ']'
+ sleep 1
+ disown 30772
+ wait
+ kill -USR1 24534
++ test
++ jobs -n
++ sed -n '/ Done / s/^\[\([0-9]*\)\]./\1/p'
+ DONE=
+ '[' -n '' ']'
+ disown 31808
+ wait
+ sleep 1
+ kill -USR1 24534
++ test
++ jobs -n
++ sed -n '/ Done / s/^\[\([0-9]*\)\].
/\1/p'
+ DONE=
+ '[' -n '' ']'
+ sleep 1
+ disown 371
+ wait
+ kill -USR1 24534
++ test
++ jobs -n
++ sed -n '/ Done / s/^\[\([0-9]*\)\]./\1/p'
+ DONE=
+ '[' -n '' ']'
+ sleep 1
+ disown 1486
+ wait
+ kill -USR1 24534
++ test
++ sed -n '/ Done / s/^\[\([0-9]*\)\].
/\1/p'
++ jobs -n
+ DONE=
+ '[' -n '' ']'
+ sleep 1
+ disown 2516
+ wait

$ + kill -USR1 24534
./p2: line 26: kill: (24534) - No such process

Ah, so this means all subprocesses completed, allowing the wait to exit. The disowned process then had nothing to kill because the script had already finished.

You can just add a

sleep 2

to the end so you don't get this message. Or, you can redirect the kill's stderr to /dev/null.