Home > Enterprise >  How to terminate 2 background processes running in bash script?
How to terminate 2 background processes running in bash script?

Time:09-20

I want these 2 background processes to end, for example, after pressing CTRL C, the only thing I found that could help, but this does not work correctly:

python3 script1.py &
python3 script2.py &
trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT

Or is there another solution to run 2 scripts in parallel? Not necessarily in the background.

CodePudding user response:

I would use something in the line of

function killSubproc(){
    kill $(jobs -p -r)
}

./test.py one 10 &
./test.py two 5 &

trap killSubproc INT
wait

It is not limited to 2 subprocess, as you can see. The idea is simply to kill all (still running) process when you hit Ctrl C jobs -p -r gives the process number of all running subprocess (-r limits to running subprocess, since some of your script may have terminated naturally ; -p gives process number, not jobs numbers)

And wait, without any argument, wait for all subprocess to end. That way, your main script is running in foreground while some subtasks are running. It still receives the ctrl c. Yet, it terminates if all your subprocess terminates naturally. And also if you hit ctrl c

Note: test.py is just a test script I've used, that runs for $2 seconds (10 and 5 here) and display $1 string each second (one and two here)

CodePudding user response:

kill -- -$$ uses $$, the the process id of the shell script, as a group ID. These aren't the same thing.

You need to get the group ID of your shell script and use that. This should work.

ps -o pgid= -p $$

Here's a complete example:

#/bin/bash -e
trap "kill -s INT -- -$(ps -o pgid= -p $$); wait" EXIT
python3 -c 'import time, signal, sys
def handler(a,b):
  print("sigint!")
  sys.exit(0)
signal.signal(signal.SIGINT, handler)
for i in range(3):
  time.sleep(1)
  print("hi from python")
' &
sleep 1

With the trap in place, you should see sigint!. With trap commented out, your python will continue to run as you've experienced yourself.

In my example I also added a wait to the trap code to make sure that when the shell script ends, all of the process group also ends.

  • Related