11

I've got a couple python scripts which I start collectively from a shell script as follows:

#!/bin/bash
python prog1.py &
python prog2.py &
python prog3.py 

Since I am developing I often want to stop these processes. I normally do so by hitting ctrl+C, but unfortuntaly a couple python programs keep (zeromq) sockets open. This means I then have to manually find them (I use lsof -i), and kill them using the PID.

So I'm looking for an easier way of automatically killing those python processes from the shell when I hit ctrl+C. On another thread here on Stackoverflow I found some code which supposedly should do what I need. I just don't understand anything about the code and how I could adjust it to my needs.

Would anybody be so kind to help me out here?

cat >work.py <<'EOF'
import sys, time, signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
for i in range(10):
    time.sleep(1)
    print "Tick from", sys.argv[1]
EOF 
chmod +x work.py

function process {
    python ./work.py $1
}

process one &
wait $!
echo "All done!"
Community
  • 1
  • 1
kramer65
  • 50,427
  • 120
  • 308
  • 488

1 Answers1

15

Let the bash script catch SIGINT, and have it kill everything in the current process group:

intexit() {
    # Kill all subprocesses (all processes in the current process group)
    kill -HUP -$$
}

hupexit() {
    # HUP'd (probably by intexit)
    echo
    echo "Interrupted"
    exit
}

trap hupexit HUP
trap intexit INT

python prog1.py &
python prog2.py &
python prog3.py &

wait
nneonneo
  • 171,345
  • 36
  • 312
  • 383
  • +1 nice, I was trying to create this same script with job control and am pretty disappointed bash doesn't offer a way to specify multiple jobs. `kill %?python` would've made sense. – kojiro Mar 21 '13 at 21:14
  • That is awesome! Thanks a lot! Just a question; I minimised your code to the code below, which appears to work the same. What's the rest for? #!/bin/bash intexit() { kill -HUP -$$; exit; } trap intexit INT python prog1.py & python prog2.py & python prog3.py – kramer65 Mar 21 '13 at 21:23
  • `hupexit` prints out a nice message, `wait` is just so that the code looks more uniform (we start everything in the background and wait). – nneonneo Mar 21 '13 at 21:30
  • but what is the trap hupexit HUP for? – kramer65 Mar 21 '13 at 21:46
  • It just allows the main script to catch the `kill HUP` and print out a nice message before exiting. – nneonneo Mar 21 '13 at 21:47
  • 1
    This works perfectly when the program is run on an ssh remote. But when I run it on a machine B, which was ssh'ed from A which in turns was ssh'ed from my local machine, ctrl + c stops all the stdout and stderr message, but the processes are still running according to top. Do you know why double ssh forwarding makes ctrl + c not work properly? – John Jiang Aug 12 '18 at 15:19