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

后端 未结 29 2570
醉酒成梦
醉酒成梦 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 05:15

    This solution uses the select module to "read any available data" from an IO stream. This function blocks initially until data is available, but then reads only the data that is available and doesn't block further.

    Given the fact that it uses the select module, this only works on Unix.

    The code is fully PEP8-compliant.

    import select
    
    
    def read_available(input_stream, max_bytes=None):
        """
        Blocks until any data is available, then all available data is then read and returned.
        This function returns an empty string when end of stream is reached.
    
        Args:
            input_stream: The stream to read from.
            max_bytes (int|None): The maximum number of bytes to read. This function may return fewer bytes than this.
    
        Returns:
            str
        """
        # Prepare local variables
        input_streams = [input_stream]
        empty_list = []
        read_buffer = ""
    
        # Initially block for input using 'select'
        if len(select.select(input_streams, empty_list, empty_list)[0]) > 0:
    
            # Poll read-readiness using 'select'
            def select_func():
                return len(select.select(input_streams, empty_list, empty_list, 0)[0]) > 0
    
            # Create while function based on parameters
            if max_bytes is not None:
                def while_func():
                    return (len(read_buffer) < max_bytes) and select_func()
            else:
                while_func = select_func
    
            while True:
                # Read single byte at a time
                read_data = input_stream.read(1)
                if len(read_data) == 0:
                    # End of stream
                    break
                # Append byte to string buffer
                read_buffer += read_data
                # Check if more data is available
                if not while_func():
                    break
    
        # Return read buffer
        return read_buffer
    

提交回复
热议问题