1

I'm using GPIO in a Python script, and I've wrapped my code in a try... except block so that GPIO is exited elegantly if I need to abort the script:

GPIO.setup(17, GPIO.OUT) # Configure GPIO so that an LED can be lit

try:
    GPIO.output(17, True) # Switch on the LED    
    #Do other stuff....

except:
        print("exiting")
        GPIO.output(17, False) # Switch off the LED
        GPIO.cleanup()

This works well - the LED is switched off if I use CTRL-C to abort the script.

Next, I start this script on reboot, via a cron job (I'm using NOOBS and it automatically boots into GUI mode). This also works well - I can see the LED light up once the script starts, and I can see the process running using ps aux | grep...

The problem is that, since it's running in the background, I need to use sudo kill to abort the script. This terminates the process but the LED remains lit, so presumably the script just dies instantly (rather than entering the except block as with CTRL-C).

How can I shutdown the GPIO elegantly when using kill to terminate a Python script which is running in the background?

  • Have code in your script which sees the signal and does the processing you require. Perhaps the Python signal module is something you should be using. The question is not really anything to do with the Raspberry Pi. – joan Apr 1 '15 at 9:24
3

I'm guessing the issue has to do with this:

Python installs a small number of signal handlers by default: [...] SIGINT is translated into a KeyboardInterrupt exception.

From here.

On linux Ctrl-C generates SIGINT, so you get an exception, which you've handled. But if you use kill:

The command kill sends the specified signal to the specified process or process group. If no signal is specified, the TERM signal is sent. The TERM signal will kill processes which do not catch this signal.

From man kill.

SIGTERM is not SIGINT, so python has not handled it and thrown you an exception. You can send any signal with kill, however (note they will only work if you have privileges on the process, which you would in this case, since you are using sudo). kill -L will give you a list of signal names with numbers that can be used as an argument, or you can use the name:

kill -s INT [pid]

That will mimic Ctrl-C. Alternately, you could install a signal handler for SIGTERM. That wikipedia bit refers to "the signal() system call"; system calls are native C, but python has an interface; you can read about that on the page from the first link, "Set handlers for asynchronous events".

  • The answers above fixed my problem. I found I needed sudo kill -2 [pid] to mimic CTRL+C. – Dave Mar 21 '17 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.