How do I close the stdout-pipe when killing a process started with python subprocess Popen?

后端 未结 3 1531
臣服心动
臣服心动 2021-02-06 03:18

I wonder if it is possible to shut down the communication pipe when killing a subprocess started in a different thread. If I do not call communicate() then kill() will work as e

3条回答
  •  傲寒
    傲寒 (楼主)
    2021-02-06 03:45

    I think the problem is that process.kill() only kills the immediate child process (bash), not the sub-processes of the bash script.

    The problem and solution are described here:

    • http://www.doughellmann.com/PyMOTW/subprocess/#process-groups-sessions
    • How to terminate a python subprocess launched with shell=True

    Use Popen(..., preexec_fn=os.setsid) to create a process group and os.pgkill to kill the entire process group. eg

    import os
    import signal
    import subprocess
    import time
    from threading import Thread
    
    process = None
    
    def executeCommand(command, runCommand):
        Thread(target=runCommand, args=(command,)).start()
    
    def runCommand(command):
        global process
        args = command.strip().split()
        process = subprocess.Popen(
            args, shell=False, stdout=subprocess.PIPE, preexec_fn=os.setsid)
    
        for line in process.communicate():
            if line:
                print "process:", line,
    
    if __name__ == '__main__':
        executeCommand("./ascript.sh", runCommand)
        time.sleep(1)
        os.killpg(process.pid, signal.SIGKILL)
    

    $ time python poc.py 
    process: sleeping five
    
    real    0m1.051s
    user    0m0.032s
    sys 0m0.020s
    

提交回复
热议问题