Home > Software engineering >  Kill a script if others have finished in bash
Kill a script if others have finished in bash

Time:01-26

I am trying to silently run scrips and a loading animation. I want the loading animation to be killed once the initial scripts have been executed, so a final script can be executed.

run A.py |
         | --> message   ∞ load animation | --> run C.py (uses A & B output)
run B.py |

I am 80% of the way but the method I have used waits for the infinite loading animation to finish before it moves on. Obviously, it never finishes and never moves on (I have a workaround but I like it less and I've invested time in trying to get this current method to work).

# Run these silently
python "/home/solebay/Project/script_a.py" &
python "/home/solebay/Project/script_b.py" &
pid=$!

# If this script is killed, stop the loading animation.
trap "kill $pid 2> /dev/null" EXIT

# While is running...
message=false
while kill -0 $pid 2> /dev/null; do
    if [ "$message" = false ]; then
      python "/home/solebay/Projects/loading_message.py" # print loading message
      message=true
    fi
    python "/home/solebay/Project/loading_animation.py" # Print looping animation
done
trap - EXIT

# Run the main script (dependent on script_a.py and script_b.py)
python "/home/solebay/Project/script_c.py"

Can I modify this approach so that it works or is it not appropriate? Everything I have tried eventually just takes it back to a state where none of it works.


Implementing Léa Gris' solution:

unset anim_pid
trap 'kill $anim_pid' EXT INT

python "/home/solebay/Project/loading_animation.py" & anim_pid=$!

python /home/solebay/Project/script_a.py & pid1=$!
python /home/solebay/Project/script_b.py & pid2=$!

# wait -n either task to finish
wait $pid1 $pid2
kill $anim_pid 2>/dev/null

printf '\n *** End of script ***\n'

CodePudding user response:

  • wait -n pid pid will wait for either pid to finish
  • wait pid pid will wait for both pid to finish
#!/usr/bin/env bash

# Do not leave animation running in case script ends
unset anim_pid
trap 'kill $anim_pid 2>/dev/null' EXT INT

animation() {
  # loop until killed
  while :; do
    for frame in '|' '/' '-' \\; do
      printf '\r%s' "$frame"
      sleep .25
    done
  done
}

task() {
  printf 'Hello I am task %d\n' "$1"
  LC_NUMERIC=C printf 'Task %d sleeping for %f seconds\n' "$1" "$2"
  sleep "$2"
  printf 'Task %d finished\n' "$1"
}

animation & anim_pid=$!

task 1 2.2 & pid1=$!
task 2 1.5 & pid2=$!

# wait both tasks to finish
wait $pid1 $pid2
kill $anim_pid 2>/dev/null
printf '\n *** End of script ***\n'
  •  Tags:  
  • Related