read subprocess stdout line by line

后端 未结 9 2207
一个人的身影
一个人的身影 2020-11-22 02:15

My python script uses subprocess to call a linux utility that is very noisy. I want to store all of the output to a log file and show some of it to the user. I thought the

9条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-22 02:54

    A function that allows iterating over both stdout and stderr concurrently, in realtime, line by line

    In case you need to get the output stream for both stdout and stderr at the same time, you can use the following function.

    The function uses Queues to merge both Popen pipes into a single iterator.

    Here we create the function read_popen_pipes():

    from queue import Queue, Empty
    from concurrent.futures import ThreadPoolExecutor
    
    
    def enqueue_output(file, queue):
        for line in iter(file.readline, ''):
            queue.put(line)
        file.close()
    
    
    def read_popen_pipes(p):
    
        with ThreadPoolExecutor(2) as pool:
            q_stdout, q_stderr = Queue(), Queue()
    
            pool.submit(enqueue_output, p.stdout, q_stdout)
            pool.submit(enqueue_output, p.stderr, q_stderr)
    
            while True:
    
                if p.poll() is not None and q_stdout.empty() and q_stderr.empty():
                    break
    
                out_line = err_line = ''
    
                try:
                    out_line = q_stdout.get_nowait()
                except Empty:
                    pass
                try:
                    err_line = q_stderr.get_nowait()
                except Empty:
                    pass
    
                yield (out_line, err_line)
    

    read_popen_pipes() in use:

    import subprocess as sp
    
    
    with sp.Popen(my_cmd, stdout=sp.PIPE, stderr=sp.PIPE, text=True) as p:
    
        for out_line, err_line in read_popen_pipes(p):
    
            # Do stuff with each line, e.g.:
            print(out_line, end='')
            print(err_line, end='')
    
        return p.poll() # return status-code
    

提交回复
热议问题