what happens to Popen()'s parent-side file descriptors?

Roger Davis rbd at hawaii.edu
Thu Oct 14 17:48:45 CEST 2010

Many thanks to all who responded to my question! It's nice to know, as
someone new to Python, that there are lots of well-informed people out
there willing to help with such issues.

Thanks, Mike, for your pipes suggestion, I will keep that in mind for
future projects.

Seebs, you are of course correct that the example I quoted (`cat |
grep | whatever`) is best done internally with the re module and built-
in language features, and in fact that has already been done wherever
possible. I should have picked a better example, there are numerous
cases where I am calling external programs whose functionality is not
duplicated by Python features.

'Nobody' (clearly a misnomer!) and Chris, thanks for your excellent
explanations about garbage collection. (Chris, I believe you must have
spent more time looking at the subprocess source and writing your
response than I have spent writing my code.) GC is clearly at the
heart of my lack of understanding on this point. It sounds like, from
what Chris said, that *any* file descriptor
would be closed when GC occurs if it is no longer referenced,
subprocess-related or not. BTW, and this comment is not at all
intended for any of you who have already very generously and patiently
explained this stuff to me, it does seem like it might be a good idea
to provide documentation on some of these more important GC details
for pretty much any class, especially ones which have lots of murky OS
interaction. I have to admit that in this case it makes perfect sense
to close parent pipe descriptors there as I can't think of any reason
why you might want to keep one open after your object is no longer
referenced or your child exits.

It sounds to me that, although my code might be safe now as is, I
probably need to do an explicit p.stdXXX.close() myself for any pipes
which I open via Popen() as soon as I am done with them. Documentation
on python.org states that GC can be postponed or omitted altogether, a
possibility that Chris mentions in his comments. Other documentation
states that there is no harm in doing multiple close()es on the same
file, so I assume that neither my code nor the subprocess GC code will
break if the other does the deed first. If anybody thinks this is a
bad idea, please comment.

On a related point here, I have one case where I need to replace the
shell construct

   externalprog <somefile >otherfile

I suppose I could just use os.system() here but I'd rather keep the
Unix shell completely out of the picture (which is why I am moving
things to Python to begin with!), so I'm just doing a simple open() on
somefile and otherfile and then passing those file handles into
Popen() for stdin and stdout. I am already closing those open()ed file
handles after the child completes, but I suppose that I probably
should also explicitly close Popen's p.stdin and p.stdout, too. (I'm
guessing they might be dup()ed from the original file handles?)

Thanks again to all!

More information about the Python-list mailing list