在 python 中杀死 sudo 启动的子进程
Killing sudo-started subprocess in python
我是 运行 用户,无需提供密码即可进行根级调用。我的用户目前正在做这样的事情
pr = subprocess.Popen("sudo sleep 100".split())
sleep(5)
pr.kill()
但这会导致此错误,因为用户不是 root,因此它无法终止 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
所以似乎从 subprocess.Popen("..").pid
返回的 pid
比进程的实际 pid 高一个 运行 我要终止的命令
我假设从 Popen
调用返回的 pid
是父进程,所以我尝试做类似
sudo kill -- -$PID
,其中 $PID
是从 Popen
返回的那个,但这只给了我
kill: sending signal to -2100 failed: No such process
为什么进程不存在?
本质上,我只需要一种方法来 运行 使用 sudo
的命令,使用 python 的子进程,然后在需要时能够终止它。我假设我需要 运行 某种类型的 sudo kill
命令和我试图杀死的进程的 pid
或类似的东西,但我无法确定具体如何做到这一点。
当您执行 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 是 'parent' 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)
我想我明白了,问题是如果我这样做
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
什么都没有出现,所以它实际上被杀死了。
我对 root 子进程有同样的问题,但这里和这里的答案 - 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
我是 运行 用户,无需提供密码即可进行根级调用。我的用户目前正在做这样的事情
pr = subprocess.Popen("sudo sleep 100".split())
sleep(5)
pr.kill()
但这会导致此错误,因为用户不是 root,因此它无法终止 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
所以似乎从 subprocess.Popen("..").pid
返回的 pid
比进程的实际 pid 高一个 运行 我要终止的命令
我假设从 Popen
调用返回的 pid
是父进程,所以我尝试做类似
sudo kill -- -$PID
,其中 $PID
是从 Popen
返回的那个,但这只给了我
kill: sending signal to -2100 failed: No such process
为什么进程不存在?
本质上,我只需要一种方法来 运行 使用 sudo
的命令,使用 python 的子进程,然后在需要时能够终止它。我假设我需要 运行 某种类型的 sudo kill
命令和我试图杀死的进程的 pid
或类似的东西,但我无法确定具体如何做到这一点。
当您执行 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 是 'parent' 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)
我想我明白了,问题是如果我这样做
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
什么都没有出现,所以它实际上被杀死了。
我对 root 子进程有同样的问题,但这里和这里的答案 - 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