Notification from Background jobs

Reposting, as it got lost during the database backup. :frowning:

Via a shell script a spawn 3 background jobs namely a, b & c.

These will take different times to complete.

I want to print a different message on completion of each.

How can i find out when each one has completed independently.

Thanks

Create a wrapper script for each task that prints the message when the wrapper completes. Then have the main script spawn each wrapper instead.

Wrapper script :confused:

Hi,
Does this approach helps?.

Gurus,
Please provide suggestions.

#!/bin/ksh
LOG_FILE=/tmp/${0##*/}.log

LogMsg() {
 print "$(date +%d/%m/%y:%H:%M:%S) : $@"  >> $LOG_FILE
}

CallA() {
 LogMsg "Calling Function A"
 iostat 5 5  >> $LOG_FILE &
 wait $!
 LogMsg "A done with $!"
 return 45
}

CallB() {
 LogMsg "Calling Function B"
 vmstat 5 5  >> $LOG_FILE &
 wait $!
 LogMsg "B done with $!"
 return 46
}

Main() {
 LogMsg "Starting the Process - Main"
 CallA
 Ret=$?
 LogMsg " Returned value $Ret "
 CallB
 Ret=$?
 LogMsg " Returned value $Ret "
}

# Call the Main Function here
Main

Thanks
Nagarajan Ganesan

But on calling CallA, the control won't return to Main till it ends, as wait ?! will wait for it.

I have to spawn all things simultaneously.

BTW what's
${0##*/} :confused:

why cant you...

start A
start B
start C
wait

where each of A, B and C do the following

print a line saying they have started
run the task
print a line saying they have ended

But inside CallA there is a wait function which will wait for the background task to complete.

Hence, until CallA completes, i won't be able to call CallB.

Tried the same with a sample script.

CallB doesn't gets called until CallA completes.

Hi,
Does this approach helps ?

#!/bin/ksh
LOG_FILE=/tmp/${0##*/}.log
/bin/rm $LOG_FILE


LogMsg() {
 print "$(date +%d/%m/%y:%H:%M:%S) : $@"  >> $LOG_FILE
}

CallA() {
 LogMsg "Calling Function A"
 iostat 5 5  >> $LOG_FILE &
 LogMsg "A done with $!"
 return $!
}

CallB() {
 LogMsg "Calling Function B"
 vmstat 5 5  >> $LOG_FILE &
 LogMsg "B done with $!"
 return $!
}

CallC() {
 LogMsg "Calling Function C"
 prstat 2 5  >> $LOG_FILE &
 LogMsg "C done with $!"
 return $!
}


Main() {
 LogMsg "Starting the Process - Main"
 CallA
 CallB
 CallC
 wait
 LogMsg "Ending the Process - Main"
}

# Call the Main Function here
Main

Thanks
Nagarajan Ganesan

Now it output A, B & C done with their respective process id's even though they still may be running in the background.

Its not waiting for them to complete. :frowning:

What does your this thing mean:
${0##*/}

S{0##*/} - To extract the name of the script

Here the functions CallA,CAllB &CallC are called from the Main function,these functions returns as soon as they start the background process,where as the Main function waits for all the background process to complete.

The message "Done with Process id" doesn't mean they are done with the background process,but meant to state the function is about to return to the caller (ie Main).

Yes,

But i need to echo the same when the background job terminates. :wink:

And also needs to fire all the jobs simultaneously.

Without waiting for one to finish.

Why is this so hard? You spawn a program with "&" and wait with "wait"

#!/bin/sh

taskA()
{
    echo taskA

    sleep 5

    echo taskA done
}

taskB()
{
    echo taskB started

    sleep 10

    echo taskB done
}

taskC()
{
    echo taskC started

    sleep 15

    echo taskC done
}

taskA &
taskB &
taskC &

echo spawned all

wait

echo done

Replace each of the sleeps with your long running tasks.

Okay,

But here i wont be able to know when TaskA has completed.

Wait will be over when all tasks are complete.

The only option i can think of is to run an infinite loop and check each process termination in that, but that will be CPU consuming as my processes will run for many hours.

Appreciate your help. :slight_smile:

Eh? Yes you will, here at point XXX you know exactly when it has finished.

taskA()
{
    echo taskA

    run_some_long_running_task

    XXX

    echo taskA done
}

If you need to do something in the parent process then use kill to send your parent a signal, and in your parent trap it.

taskAfinished()
{
   echo "wow!"
}

trap taskAfinished 16

mainPid=$$

taskA()
{
     runA
     kill -16 $mainPid 
}

taskA &
wait

Hmmm,

This seems to be a good idea.

I never wondered i can call a function in the background.

Now i can call many functions simultaneously.

Thanks

Oops,

You did run functions in background in your earlier post.

Sorry for not noticing that. :o

Glad to be of help.

All the best for future also. :smiley: