我在Python中编写了一个GTK GUI应用程序来调用shell脚本并将调用参数从GUI传递给脚本,并在文本窗口中返回脚本结果。
现在我想允许用户从GUI取消正在运行的shell脚本。该脚本以Popen开头。如果我以普通用户的身份调用它,它可以正常工作(在下面的代码中标记sudo = False)。当我使用sudo来调用脚本时,我无法再取消它。我发现如果我使用shell = True,报告kill的人将无效,所以我用shell = False测试它,但它也不起作用。
我将我的问题删除到以下代码段:
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 >> 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"
我实际上已经遇到了使用os.kill将脚本作为普通用户取消的问题,但后来发现我必须使用os.setuid和killpg来杀死正在运行的shell。我是线程新手,可能只是一个简单的Linux线程误解了我...
答案 0 :(得分:3)
如果你用sudo启动它,你必须拥有root权限才能杀死它。基本上,你必须这样做:
os.system("sudo kill %d"%(pid))
另外,出于安全考虑,我建议您以root身份创建bash脚本,将其放在任何方便的地方,不要让用户对它进行写入访问,最后设置sudo来运行它而不需要密码。这将无需在此python脚本中存储密码。
答案 1 :(得分:1)
TL; DR;
处理此问题的一种更优雅的方法是使用pyexpect而不是“subprocess.Popen”启动该过程。
spawnProcess = pexpect.spawn(command)
然后,当你想要“杀死”这个过程时,你只需要:
spawnProcess.sendcontrol("c")
说明:
从os.system运行sudo kill是一个肮脏的黑客,需要用户再次输入密码或要求你存储root密码只是为了让你杀死一个子进程。在我的情况下,它更糟糕,因为该进程不是以sudo启动的,它是setuid root可执行文件,因此目标用户实际上没有sudo访问权限。
事实证明,来自bash的“CTRL + C”与kill -INT不同,因为很多人都会让你相信。你可以“CTRL + C”一个以sudo或setuid root开头的进程,但是你不能将SIGINT发送给进程。我在这里找到了解释:
知道只有“CTRL + C”真的有用,我设计了一个模仿用户会做什么的解决方案,它就像一个魅力!