How to kill a shell script invoked with Popen with sudo?
<p>I wrote a GTK GUI application in Python to just invoke a shell script and pass invocation parameters to the script from the GUI and return the script results in a text window. </p>

<p>Now I like to allow the user to cancel a running shell script from the GUI. The script is started with Popen. It works fine if I invoke it as a normal user (flag sudo=False in the code below). When I use sudo to invoke the script I cannot cancel it any more. I found people reporting kill will not work if I use shell=True, so I tested it with shell=False but it doesn't work either. </p>

<p>I stripped down my issue to the following code snippet:</p>

<pre><code>import os
import signal
import subprocess
import time
import sys
import shlex

bashScriptFileName="t.sh"

f = open(bashScriptFileName,'w')

f.write("""#!/bin/bash
on_die()
{
    echo "Dying..."
    exit 0
}  

trap 'on_die' TERM

SEC=0
while true ; do
    sleep 1
    SEC=$((SEC+1))
    echo "I'm PID# $$, and I'm alive for $SEC seconds now!"
done

exit 0""")
f.close()
os.chmod(bashScriptFileName, 0755)

shell=True      # flag to enable/disable shell invocation of Popen
sudo=True       # flag to invoke command with sudo

if sudo:
    commandToExecute='sudo -S '+ bashScriptFileName
else:
    commandToExecute='./' + bashScriptFileName

if not shell:
    commandToExecute = shlex.split(commandToExecute)

print "Command: %s" % (commandToExecute)                                

proc = subprocess.Popen(commandToExecute, stdin=subprocess.PIPE, close_fds=False,shell=shell, preexec_fn=os.setsid)
print &gt;&gt; proc.stdin, "secretPassword"                
print 'PARENT      : Pausing before sending signal to child %s...' % proc.pid
sys.stdout.flush()
time.sleep(5)
print 'PARENT      : Signaling child %s' % proc.pid
sys.stdout.flush()
os.killpg(proc.pid, signal.SIGTERM)
time.sleep(3)
print "Done"
</code></pre>

<p>I actually already had problems to get the script canceled as a normal user with os.kill but then found out I have to use os.setuid and killpg to kill the running shell. I'm new to threading and it may be just a simple Linux threading misunderstanding from my side ...</p>
