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

后端 未结 29 2565
醉酒成梦
醉酒成梦 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:13

    I also faced the problem described by Jesse and solved it by using "select" as Bradley, Andy and others did but in a blocking mode to avoid a busy loop. It uses a dummy Pipe as a fake stdin. The select blocks and wait for either stdin or the pipe to be ready. When a key is pressed stdin unblocks the select and the key value can be retrieved with read(1). When a different thread writes to the pipe then the pipe unblocks the select and it can be taken as an indication that the need for stdin is over. Here is some reference code:

    import sys
    import os
    from select import select
    
    # -------------------------------------------------------------------------    
    # Set the pipe (fake stdin) to simulate a final key stroke
    # which will unblock the select statement
    readEnd, writeEnd = os.pipe()
    readFile = os.fdopen(readEnd)
    writeFile = os.fdopen(writeEnd, "w")
    
    # -------------------------------------------------------------------------
    def getKey():
    
        # Wait for stdin or pipe (fake stdin) to be ready
        dr,dw,de = select([sys.__stdin__, readFile], [], [])
    
        # If stdin is the one ready then read it and return value
        if sys.__stdin__ in dr:
            return sys.__stdin__.read(1)   # For Windows use ----> getch() from module msvcrt
    
        # Must finish
        else:
            return None
    
    # -------------------------------------------------------------------------
    def breakStdinRead():
        writeFile.write(' ')
        writeFile.flush()
    
    # -------------------------------------------------------------------------
    # MAIN CODE
    
    # Get key stroke
    key = getKey()
    
    # Keyboard input
    if key:
        # ... do your stuff with the key value
    
    # Faked keystroke
    else:
        # ... use of stdin finished
    
    # -------------------------------------------------------------------------
    # OTHER THREAD CODE
    
    breakStdinRead()
    

提交回复
热议问题