【问题标题】:Python how to kill root subprocessPython如何杀死根子进程
【发布时间】:2018-07-09 08:23:51
【问题描述】:

我正在尝试以 root 权限启动一个进程并稍后将其终止。

但由于某种原因,我无法让它工作。

这是一个重现我的问题的小脚本(免责声明:代码有点脏,仅用于重现错误)

import os
import time
import subprocess

command = ["sudo", "sleep", "25"]

process = subprocess.Popen(command,
                           bufsize=1,
                           stdin=open(os.devnull),
                           stderr=subprocess.PIPE,
                           stdout=subprocess.PIPE)

def kill():
    pid = process.pid
    cmd = "sudo kill %s" % pid
    print(cmd)
    print(os.system(cmd))

time.sleep(2)
kill()

stdout, stderr = process.communicate()
print("stdout: " + stdout)
print("stderr: " + stderr)
ret = process.wait()
print("ret: " + str(ret))

这段代码似乎无法杀死我的子进程,但是当我在另一个 python 实例中启动 os.system("sudo kill <pid>") 时,它确实有效。

【问题讨论】:

  • 为什么不使用 sudo python script 启动程序,它将以所需的权限运行。只需在脚本中使用os.kill( pid, sig)
  • 是的,这将是一个解决方案,但如果可能的话,我们不希望我们的脚本以 root 身份运行
  • 然后使用 sudo 以您想要的非 root 用户身份运行它:sudo -u ...
  • 这里的目标仍然是以root身份运行命令(而不是脚本)
  • 也许可以添加print os.getuid() / is.geteuid() 来确定您是否与用户有问题

标签: python subprocess root sudo kill


【解决方案1】:

您的代码中的问题是,它没有在 kill 函数中关闭线程

函数kill 确实会杀死您的子进程命令。但它并没有结束线程。

注意:如果要强制完全终止进程,请使用 -9。

您的问题的解决方案是。在 kill 函数中使用 process.wait() (这将关闭你的线程)。

def kill():
    pid = process.pid
    cmd = "sudo kill -9 %s" % pid . # -9 to kill force fully
    print(cmd)
    print(os.system(cmd))
    print(process.wait()) # this will print -9 if killed force fully, else -15.

【讨论】:

  • 谢谢,它有效,但不完全是因为现在我无法获得进程stdout和stderr,(这对我来说非常重要),你知道怎么做吗?跨度>
  • 所以在你杀死你的程序之前获取标准输出和标准错误。
  • 是的,但我不会每次都杀死它,有时进程会自行结束,如果我使用 subprocess.communicate 杀死它会挂起
  • 如果你使用python 3.3+用户subprocess.check_output,你可以提供time_out。否则结帐bo-yang.net/2016/12/01/python-run-command-with-timeout
  • 好的,现在可以了:我现在在做 process.wait(),如果 ret != signal 然后我做 process.communicate()
【解决方案2】:

你也可以试试这个。在这里,我尝试做的是为可能在子进程调用期间创建的进程组设置一个会话 ID,当你想要杀死时,一个信号被发送到进程组负责人,它被传输到这个的所有子进程组。

import signal
process = subprocess.Popen(command,
                       stderr=subprocess.PIPE,
                       stdout=subprocess.PIPE,
                       preexec_fn=os.setsid)   # add session id to group

print(process.pid)

def kill():
    pid = process.pid
    cmd = "sudo kill %s" % pid
    print(cmd)
    os.killpg(os.getpgid(process.pid), signal.SIGTERM)  # send signal to the group

time.sleep(2)
kill()

【讨论】:

  • 好主意,并且以更 Python 的方式,我刚刚尝试过,它实际上解锁了 Python,但遗憾的是它会产生僵尸......
猜你喜欢
  • 2010-12-08
  • 1970-01-01
  • 2011-09-26
  • 2014-06-19
  • 1970-01-01
  • 2015-04-17
  • 1970-01-01
相关资源
最近更新 更多