非根用户,如何在Python 2.4中杀死子进程

2 投票
2 回答
5830 浏览
提问于 2025-04-16 06:58

我想要在一个子进程执行时间太长的时候把它杀掉。
我知道我需要用到 os.kill 或者 os.killpg

但是问题来了,如果我不是以管理员身份运行的话,就会出现麻烦。比如说,在我设计的图形界面(GUI)中,我想调用一个子进程,然后用 os.killos.killpg 来结束这个子进程。但我的图形界面是由apache这个用户拥有的。所以当我执行 os.kill 命令的时候,就会报错:

[type: 
exceptions.OSError value: [Errno 1] Operation not permitted 

而且,我的python版本是 2.4.3,所以不能使用 terminate() 方法。

有没有人能给我一些建议呢?

非常感谢!

附注:
我代码中相关的部分:

timeout=4
subp = subprocess.Popen('sudo %s'%commandtosend, shell=True,preexec_fn=os.setsid, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    while subp.poll() is None:
        time.sleep(0.1)
        now = datetime.datetime.now()
        if (now - start).seconds > timeout:
            os.kill(subp.pid, signal.SIGKILL)
            #os.killpg(subp.pid, signal.SIGKILL)
            break

2 个回答

3

你的子进程是以超级用户权限运行的(因为你是用sudo来启动它的)。要结束这个进程,你也需要是超级用户。

一种选择是不要使用os.kill,而是直接运行'sudo kill 5858',其中5858是由subprocess.Popen启动的进程的PID(进程ID)。

另外需要注意的是,如果你的程序允许用户控制commandtosend,那么你就相当于给了用户对整个机器的超级用户权限。

5

如果可以的话,尽量把 sudo 从子进程的命令中去掉。这样做是因为不应该在图形界面下以超级用户的身份运行子进程,这样做会有安全隐患。

subprocess.Popen(commandtosend, shell=True,preexec_fn=os
                 ^^
                 Here don't put sudo

这样一来,你的子进程就会以 www-data 用户(也就是 Apache 用户)的身份启动,你可以用 os.kill(subp.pid, signal.SIGKILL) 来结束它。

如果实在无法去掉 sudo(这其实是不好的做法),那么你就得这样来执行结束操作:

os.system("sudo kill %s" % (subp.pid, ))

希望这些能帮到你 :)

撰写回答