Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to wait for first command to finish?

Tags:

linux

bash

I am writing a script in bash, which is calling two bash scripts internally. Where first script includes different tests which runs in background and second script print results of first script.

When I run these two scripts one after other, sometimes, second script get executed before first script ends Which prints wrong results.

I am running both scripts with source command. Any better suggestions?

source ../../st_new.sh -basedir $STRESS_PATH -instances $INSTANCES 
source ../../results.sh
like image 581
Pravin Junnarkar Avatar asked Apr 27 '15 06:04

Pravin Junnarkar


2 Answers

Shell scripts, no matter how they are executed, execute one command after the other. So your code will execute results.sh after the last command of st_new.sh has finished.

Now there is a special command which messes this up: &

cmd &

means: "Start a new background process and execute cmd in it. After starting the background process, immediately continue with the next command in the script."

That means & doesn't wait for cmd to do it's work. My guess is that st_new.sh contains such a command. If that is the case, then you need to modify the script:

cmd &
BACK_PID=$!

This puts the process ID (PID) of the new background process in the variable BACK_PID. You can then wait for it to end:

while kill -0 $BACK_PID ; do
    echo "Process is still active..."
    sleep 1
    # You can add a timeout here if you want
done

or, if you don't want any special handling/output simply

wait $BACK_PID

Note that some programs automatically start a background process when you run them, even if you omit the &. Check the documentation, they often have an option to write their PID to a file or you can run them in the foreground with an option and then use the shell's & command instead to get the PID.

like image 58
Aaron Digulla Avatar answered Oct 18 '22 01:10

Aaron Digulla


Make sure that st_new.sh does something at the end what you can recognize (like touch /tmp/st_new.tmp when you remove the file first and always start one instance of st_new.sh).
Then make a polling loop. First sleep the normal time you think you should wait, and wait short time in every loop. This will result in something like

max_retry=20
retry=0
sleep 10 # Minimum time for st_new.sh to finish
while [ ${retry} -lt ${max_retry} ]; do
   if [ -f /tmp/st_new.tmp ]; then
      break # call results.sh outside loop
   else
      (( retry = retry + 1 ))
      sleep 1
   fi
done
if [ -f /tmp/st_new.tmp ]; then
   source ../../results.sh 
   rm -f /tmp/st_new.tmp
else
   echo Something wrong with st_new.sh
fi
like image 26
Walter A Avatar answered Oct 18 '22 00:10

Walter A