在python中杀死sudo-started子进程

时间:2018-05-31 06:56:49

标签: python linux subprocess sudo kill

我正在与一个可以进行根级别调用而无需提供密码的用户一起运行。我的用户目前正在做类似的事情

pr = subprocess.Popen("sudo sleep 100".split())
sleep(5)
pr.kill()

但这会导致此错误,因为用户不是root用户,因此无法终止根进程

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/subprocess.py", line 1572, in kill
    self.send_signal(signal.SIGKILL)
  File "/usr/lib/python2.7/subprocess.py", line 1562, in send_signal
    os.kill(self.pid, sig)
OSError: [Errno 1] Operation not permitted

所以我尝试做这样的事情

pr = subprocess.Popen("sudo sleep 100".split())
sleep(5)
kill_pr = subprocess.Popen("sudo kill {}".format(pr.pid))

但这并没有杀死有问题的程序。例如,如果

>> subprocess.Popen("sudo sleep 100".split()).pid
5000

$ pgrep sleep
5001

所以从pid返回的subprocess.Popen("..").pid似乎比运行我要杀死的命令的进程的实际pid高一个

我假设从pid调用返回的Popen是父进程,所以我尝试做类似的事情

sudo kill -- -$PID,其中$PID是从Popen返回的,但这只是给了我

kill: sending signal to -2100 failed: No such process

为什么这个过程不存在?

基本上,我只需要一种方法使用python的子进程运行sudo命令,然后在需要时能够杀死它。我假设我需要运行某种类型的sudo kill命令与{I}尝试杀死的过程的pid但我无法确定究竟该怎么做。

3 个答案:

答案 0 :(得分:2)

执行pgrep sleep时,会显示sleep命令的PID,作为您创建的sudo进程的子项运行。

作为快速演示,我将以下内容保存为subproc.py

import subprocess
pr = subprocess.Popen(["sudo", "sleep", "100"])
print("Process spawned with PID: %s" % pr.pid)

运行此脚本时,我们可以看到产生的两个进程:

~/$ python subproc.py
Process spawned with PID: 5296

~/$ ps all | grep sleep
    0  5296     1     sudo sleep 100
    0  5297  5296     sleep 100

您会注意到您在代码中知道的PID是'父'sudo进程。这是你应该杀死的过程,但是你需要使用sudo来执行它:

subprocess.check_call(["sudo", "kill", str(pr.pid)])
#You might want to wait for the process to end:
os.waitpid(pr.pid, 0)

答案 1 :(得分:1)

我想我弄清楚了,问题是如果我这样做了

import subprocess, os
pr = subprocess.Popen(["sudo", "sleep", "100"])
print("Process spawned with PID: %s" % pr.pid)
pgid = os.getpgid(pr.pid)
subprocess.check_output("sudo kill {}".format(pgid))

它会杀死启动python解释器的进程

>>> Terminated

因此,我将preexec_fn设置为os.setpgrp

import subprocess, os
pr = subprocess.Popen(["sudo", "sleep", "100"], preexec_fn=os.setpgrp)
print("Process spawned with PID: %s" % pr.pid)
pgid = os.getpgid(pr.pid)
subprocess.check_output("sudo kill {}".format(pgid))

在另一个shell中,如果我检查

pgrep sleep

什么都没有出现,所以它实际上已经被杀死了。

答案 2 :(得分:0)

我对根子进程也有同样的问题,但是这里和这里的答案Python how to kill root subprocess都不适合我。

最后唯一起作用的是:

proc = subprocess.Popen(["sudo", exe_path], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
.
.
.
os.system("sudo pkill -9 -P " + str(proc.pid))

不需要-preexec_fn = os.setpgrp