I have a Python code like this.
try:
while some_cond_is_still_true:
....
except KeyboardInterrupt: # Handle CTRL+C
...
While the KeyboardInterrupt is handled fine if I run the python script by myself, it is not handled if I run it as another user using su, like this.
su <some_other_user> -c 'python myprogram.py <args>'
How can I solve this problem?
The su command creates a new interactive shell and executes the command inside it.
When you use option -c (--command) the su command creates a new session with the user indicated in the command. To solve this use the option --session-command.
In this case the command will be this:
su user_name --session-command 'python myprogram.py <args>'
in this case you should be able to catch CTRL+C interrupt.
What The Bndr said is true. To solve this problem you can use the signal module to register a new callback function that will be called at SIGTERM signal. In it you can either raise a KeyboardInterrupt() or set a global variable that controls the program's flow to False. You can also try registering the default callback again, which does raise the KeyboardInterrupt() exception.
This should make the newly spawned shell propagate the signal correctly. If it doesn't, then you should choose the shell which will launch the script through su, because something is wrong with the one called at this moment. Or check your execute line at the top of your script. Try playing with it with combinations of calls to the script like:
#! /usr/bin/env python
or
#! /usr/bin/python
or
#! /bin/sh python
or
#! /bin/bash python
and so on, and see what works. This assumes your script is made executable and you do not have to call Python interpreter directly. If you plan to distribute your script though, be careful what you leave there. Different distributions will react differently and some even may not have the problem you are currently experiencing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With