[Tutor] "standard output: Broken pipe"

Eric Brunson brunson at brunson.com
Mon Oct 22 04:56:08 CEST 2007


I'm coming in late to the discussion and thought that someone would 
explain it succinctly, but there have been so many correct statements 
which I feel fail to nail down the problem that I thought I'd chime in.

Here's the important concepts to understand.  The pipe is a construct of 
the shell, you are spawning a shell to run your entire command line.  
When the "make" finishes and stops accepting the input from "yes", the 
kernel sends a SIGPIPE to the parent process, i.e. the shell.  The 
shell's default behavior when receiving the SIGPIPE is to print an error 
message.

Your problem, as I interpret it, is that you don't like seeing the error 
message.  So you have two choices:  1) find some way to filter it, 
because all it is is a message, or 2) get rid of the shell and handle 
the management of the subprocesses yourself.  It's been discussed how to 
suppress the output and it's been discussed how to intercept the signal, 
but I don't thing that anyone has pointed to the definitive python 
construct to handle it properly. 

You've had several responses that correctly tell you how to handle a 
signal, but without any testing I'm pretty sure that none of that will 
do you any good with the subprocess.call() construct you're using.  The 
shell is your subprocess and it is already handling the signal, so you 
should never see it.  The trick is to spawn both processes via python 
*without* an intervening shell to interfere.  Here's the canonical 
example: http://docs.python.org/lib/node536.html.  You can spawn each 
subprocess, 'yes' and 'make' without the shell being required to pipe 
the output of one to the other, you can do it all completely in python.

Again, sorry to come in late, but while reading many absolutely factual 
an correct responses, they all seemed to be either handling the output 
or discussing signal handling without, in my mind, pointing out that 
it's the shell that's giving you the problems.  I think it's Python's 
default behavior to ignore SIGPIPE, as Martin comments on in his latest 
reply.  It's just that the shell has already accepted and handled the 
signal.

Interestingly, when you eliminate the shell and use something similar to 
the example code from above, you can pretty easily see how to get rid of 
the 'yes' and just feed the make subprocess input yourself, further 
simplifying the code.

I'll admit, I've stated all this without actually running any test, so 
please, if anyone can show differently, I'm happy to have my 
understanding corrected.

I hope that helps, not only with your specific problem, but from a "big 
picture" standpoint, also.  Nothing I hate more than writing code that I 
don't really understand.  :-)

e.

James wrote:
> Hi,
>
> I have a snippet of code in a Python script I'm whipping up that's  
> causing a not-so-pretty output.  Here's the code:
>
> subprocess.call( "yes '' | make oldconfig" , shell=True )
>
> When I run this code, Python loyally executes the command, and then I  
> see the following error on my console:
>
> -----
>
> yes: standard output: Broken pipe
> yes: write error
>
> -----
>
> I did some Googling and I believe found the reason for this error  
> ("yes" executes forever, and complains when Python kills the process  
> off).  However, I'd like to figure out a way to get rid of the error  
> (or hide it) so that it's not visible to the person running the  
> script (it's not the prettiest thing to see scroll by your screen :)).
>
> Thoughts / ideas?
>
> Thanks!
> .james
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
>   



More information about the Tutor mailing list