1

I'm calling a child process using subprocess.Popen (Python 2.x on a POSIX system). I want to be able to read the output of the child process using Python's readline() file object function. However, the stream available in Popen.stdout does not appear to have a readline() method.

Using the idea from Python readline from pipe on Linux, I tried the following:

p = subprocess.Popen(
    [sys.executable, "child.py"],
    stdout=subprocess.PIPE)
status = os.fdopen(p.stdout.fileno())
while True:
    s = status.readline()
    if not s:
        break
    print s

However, the problem with this method is that both the p.stdout object and the new status object attempt to close the single file descriptor. This eventually results in:

close failed: [Errno 9] Bad file number

Is there a way to create a file object that "wraps" a previously created file-like object?

Community
  • 1
  • 1
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 1
    how do you get `p.stdout` that has `.fileno()` but no `.readline()` method? – jfs Jan 24 '12 at 04:43
  • @J.F.Sebastian: That's a good question. I just tried again and `p.stdout.readline()` works fine. It's possible that I had mistakenly tried `p.readline()`, which is sort of embarrassing. – Greg Hewgill Jan 24 '12 at 05:16

1 Answers1

2

The solution is to use os.dup() to create another file descriptor referring to the same pipe:

status = os.fdopen(os.dup(p.stdout.fileno()))

This way, status has its own file descriptor to close.

user unknown
  • 35,537
  • 11
  • 75
  • 121
Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285