简体   繁体   中英

python popen.stdout.readline() hangs

I am having a problem... does anyone knows why this code hangs in the while loop. The loop doesn't seem to catch the last line of the stdout .

working_file = subprocess.Popen(["/pyRoot/iAmACrashyProgram"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)

line = working_file.stdout.readline()
working_file.stdout.flush()
while working_file != "" :
    print(line)
    line = working_file.stdout.readline()
    working_file.stdout.flush()

The script hangs with the curser just blinking when readline() is encountered. I don't understand why. Can anyone shed some light?

Does doing a nonblocking read help you out?

import fcntl
import os

def nonBlockReadline(output):
    fd = output.fileno()
    fl = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
    try:
        return output.readline()
    except:
        return ''

working_file = subprocess.Popen(["/pyRoot/iAmACrashyProgram"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)

line = nonBlockReadline(working_file.stdout)
working_file.stdout.flush()
while working_file != "" :
    print(line)
    line = nonBlockReadline(working_file.stdout)
    working_file.stdout.flush()

I'm not sure exactly what you're trying to do, but will this work better? It just reads all the data, instead of reading only one line at a time. It's a little more readable to me.

import fcntl
import os

def nonBlockRead(output):
    fd = output.fileno()
    fl = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
    try:
        return output.read()
    except:
        return ''

working_file = subprocess.Popen(["/pyRoot/iAmACrashyProgram"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)

stdout = ''

while working_file.poll() is None:
    stdout += nonBlockRead(working_file.stdout)

# we can probably save some time and just print it instead...
#print(stdout)

stdout = stdout.splitlines()
for line in stdout:
    print(line)

Edit: A generalized script which should be more suited for your use case:

import fcntl
import os

def nonBlockRead(output):
    fd = output.fileno()
    fl = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
    try:
        return output.read()
    except:
        return ''

working_file = subprocess.Popen(["/pyRoot/iAmACrashyProgram"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)

while working_file.poll() is None:
    stdout = nonBlockRead(working_file.stdout)

    # make sure it returned data
    if stdout:
        # process data
        working_file.stdin.write(something)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM