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.