How to kill a python child process created with subprocess.check_output() when the parent dies?

后端 未结 5 1837
再見小時候
再見小時候 2020-11-27 05:17

I am running on a linux machine a python script which creates a child process using subprocess.check_output() as it follows:

subprocess.check_output([\"ls\",         


        
5条回答
  •  南笙
    南笙 (楼主)
    2020-11-27 06:10

    Don't know the specifics, but the best way is still to catch errors (and perhaps even all errors) with signal and terminate any remaining processes there.

    import signal
    import sys
    import subprocess
    import os
    
    def signal_handler(signal, frame):
        sys.exit(0)
    signal.signal(signal.SIGINT, signal_handler)
    
    a = subprocess.check_output(["ls", "-l"], stderr=subprocess.STDOUT)
    
    while 1:
        pass # Press Ctrl-C (breaks the application and is catched by signal_handler()
    

    This is just a mockup, you'd need to catch more than just SIGINT but the idea might get you started and you'd need to check for spawned process somehow still.

    http://docs.python.org/2/library/os.html#os.kill http://docs.python.org/2/library/subprocess.html#subprocess.Popen.pid http://docs.python.org/2/library/subprocess.html#subprocess.Popen.kill

    I'd recommend rewriting a personalized version of check_output cause as i just realized check_output is really just for simple debugging etc since you can't interact so much with it during executing..

    Rewrite check_output:

    from subprocess import Popen, PIPE, STDOUT
    from time import sleep, time
    
    def checkOutput(cmd):
        a = Popen('ls -l', shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
        print(a.pid)
        start = time()
        while a.poll() == None or time()-start <= 30: #30 sec grace period
            sleep(0.25)
        if a.poll() == None:
            print('Still running, killing')
            a.kill()
        else:
            print('exit code:',a.poll())
        output = a.stdout.read()
        a.stdout.close()
        a.stdin.close()
        return output
    

    And do whatever you'd like with it, perhaps store the active executions in a temporary variable and kill them upon exit with signal or other means of intecepting errors/shutdowns of the main loop.

    In the end, you still need to catch terminations in the main application in order to safely kill any childs, the best way to approach this is with try & except or signal.

提交回复
热议问题