A non-blocking read on a subprocess.PIPE in Python

后端 未结 29 2689
醉酒成梦
醉酒成梦 2020-11-21 04:49

I\'m using the subprocess module to start a subprocess and connect to its output stream (standard output). I want to be able to execute non-blocking reads on its standard ou

29条回答
  •  心在旅途
    2020-11-21 04:56

    This version of non-blocking read doesn't require special modules and will work out-of-the-box on majority of Linux distros.

    import os
    import sys
    import time
    import fcntl
    import subprocess
    
    def async_read(fd):
        # set non-blocking flag while preserving old flags
        fl = fcntl.fcntl(fd, fcntl.F_GETFL)
        fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
        # read char until EOF hit
        while True:
            try:
                ch = os.read(fd.fileno(), 1)
                # EOF
                if not ch: break                                                                                                                                                              
                sys.stdout.write(ch)
            except OSError:
                # waiting for data be available on fd
                pass
    
    def shell(args, async=True):
        # merge stderr and stdout
        proc = subprocess.Popen(args, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
        if async: async_read(proc.stdout)
        sout, serr = proc.communicate()
        return (sout, serr)
    
    if __name__ == '__main__':
        cmd = 'ping 8.8.8.8'
        sout, serr = shell(cmd.split())
    

提交回复
热议问题