代码之家  ›  专栏  ›  技术社区  ›  John Allard

在python中杀死sudo启动的子进程

  •  1
  • John Allard  · 技术社区  · 6 年前

    我运行的用户可以进行根级别的调用,而无需提供密码。我的用户当前执行的操作如下

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

    但是这会导致这个错误,因为用户不是根用户,所以它不能终止根进程

    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 是从 波彭 ,但这让我

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

    为什么这个过程不存在?

    实际上,我只需要一种方法来运行命令 sudo 使用python的子进程,然后可以在需要时杀死它。我想我需要 sudo kill 使用命令 PID 我想杀掉的过程或类似的事情,但我无法确定具体怎么做。

    2 回复  |  直到 6 年前
        1
  •  3
  •   Steve Mayne    6 年前

    当你执行 pgrep sleep 您将看到 sleep 命令,作为 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)
    
        2
  •  2
  •   John Allard    6 年前

    我想我明白了,问题是如果我这么做

    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))
    

    在另一个壳里,如果我检查

    pgrep sleep
    

    什么也没出现,所以它真的被杀死了。