[Tutor] "standard output: Broken pipe"

Martin Walsh mwalsh at groktech.org
Mon Oct 22 03:27:34 CEST 2007


Michael Langford wrote:
> 
> This signal is not something you care about. All SIGPIPE means is that
> the source of the signal found itself writing to a pipe with no sender.
> Your line  "signal.signal(signal.SIGPIPE, signal.SIG_DFL)" means use the
> default signal handler for SIGPIPE. While this works (as the default
> signal handler is the ignore handler, you actually want to explicitly
> use the IGN handler, which will just ignore the signal.  To do this use
> " signal.signal(signal.SIGPIPE, signal.SIG_IGN)"

I don't think this is quite right, but please correct me if I'm
misinformed, or just plain wrong. :)

Using "signal.signal(signal.SIGPIPE, signal.SIG_IGN)" (kernel 2.6.20,
bash 3.2, python2.5) still produces a broken pipe with the following code:

import signal
import subprocess as sp
signal.signal(signal.SIGPIPE, signal.SIG_IGN)
sp.call("yes 'Spam' | head -n 10", shell=True)

My understanding is that python is *already* overriding with a SIG_IGN
for SIGPIPE, and child processes inherit, which explains the difference
in behavior when running the command from a shell terminal (on my system
at least) vs. a python subprocess object. This is referenced in the
signal module docs (http://docs.python.org/lib/module-signal.html), and
appears to be confirmed in the python2.5 source (pythonrun.c).

Also, while it is unclear in the signal module docs (to me at least), my
take on the use of SIG_DFL is to revert (if necessary) to the *system*
default action for a signal, not the python default (which is SIG_IGN).
Again, this is my interpretation based on a very minimal understanding
-- please correct me if I'm wrong.

> 
> The reason you don't see the error on the shell is that the bash shell
> does not print notifications of SIGPIPE when running interactively. If
> you instead copied your snippit of scripting into a shell script then
> called that with "bash foo.sh", you'd see the exact same broken pipe.

Ok, this isn't true on my system either -- I don't get a broken pipe
from a bash script. So, perhaps this is due to the differences in our
kernel or bash versions. The version of bash on my system (3.2) has a
DONT_REPORT_SIGPIPE define that is honored in both interactive and
non-interactive shells. Presumably, this is how the ubuntu binary was
compiled.

> 
> Here is what all the signals available do:
> http://www.delorie.com/gnu/docs/glibc/libc_471.html
> 

Excellent link, thanks! IMO, the signal manpage ('man signal') is also a
good resource. On my system, it contains a table of default actions.
Here's what it has to say about SIGPIPE:

"""
Signal     Value     Action   Comment
-------------------------------------
SIGPIPE      13       Term    Broken pipe: write to pipe with no readers
"""

and, the 'Term' action is defined as follows:

"""
Term   Default action is to terminate the process.
"""

Thanks!
Marty


More information about the Tutor mailing list