Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I find out why subprocess.Popen wait() waits forever if stdout=PIPE?

I have a program that writes to stdout and possibly stderr. I want to run it from python, capturing the stdout and stderr. My code looks like:

from subprocess import *  p = Popen( exe, shell=TRUE, stdout=PIPE, stderr=PIPE ) rtrncode = p.wait() 

For a couple of programs, this works fine, but when I added a new one, the new one hangs forever. If I remove stdout=PIPE, the program writes its output to the console and finishes and everything is fine. How can I determine what's causing the hang?

Using python 2.5 on Windows XP. The program does not read from stdin nor does it have any kind of user input (i.e. "hit a key").

like image 718
Graeme Perrow Avatar asked Sep 18 '09 16:09

Graeme Perrow


People also ask

Does Popen have a timeout?

The timeout argument is passed to Popen. communicate() . If the timeout expires, the child process will be killed and waited for. The TimeoutExpired exception will be re-raised after the child process has terminated.

Does subprocess call wait for completion?

The subprocess module provides a function named call. This function allows you to call another program, wait for the command to complete and then return the return code.

Does Popen need to be closed?

Popen do we need to close the connection or subprocess automatically closes the connection? Usually, the examples in the official documentation are complete. There the connection is not closed. So you do not need to close most probably.

What is pipe in Popen?

The popen() function executes the command specified by the string command. It creates a pipe between the calling program and the executed command, and returns a pointer to a stream that can be used to either read from or write to the pipe.


2 Answers

When a pipe's buffer fills up (typically 4KB or so), the writing process stops until a reading process has read some of the data in question; but here you're reading nothing until the subprocess is done, hence the deadlock. The docs on wait put it very clearly indeed:

Warning This will deadlock if the child process generates enough output to a stdout or stderr pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use communicate() to avoid that.

If you can't use communicate for some reason, have the subprocess write to a temporary file, and then you can wait and read that file when it's ready -- writing to a file, instead of to a pipe, does not risk deadlock.

like image 108
Alex Martelli Avatar answered Oct 23 '22 13:10

Alex Martelli


Take a look at the docs. It states that you shouldn't use wait as it can cause a dead lock. Try using communicate.

like image 30
MitMaro Avatar answered Oct 23 '22 15:10

MitMaro