IOError: [Errno 32] Broken pipe: Python
The problem is due to SIGPIPE handling. You can solve this problem using the following code:
from signal import signal, SIGPIPE, SIG_DFL
signal(SIGPIPE,SIG_DFL)
See here for background on this solution. Better answer here.
To bring Alex L.'s helpful answer, akhan's helpful answer, and Blckknght's helpful answer together with some additional information:
Standard Unix signal
SIGPIPE
is sent to a process writing to a pipe when there's no process reading from the pipe (anymore).- This is not necessarily an error condition; some Unix utilities such as
head
by design stop reading prematurely from a pipe, once they've received enough data.
- This is not necessarily an error condition; some Unix utilities such as
By default - i.e., if the writing process does not explicitly trap
SIGPIPE
- the writing process is simply terminated, and its exit code is set to141
, which is calculated as128
(to signal termination by signal in general) +13
(SIGPIPE
's specific signal number).By design, however, Python itself traps
SIGPIPE
and translates it into a PythonIOError
instance witherrno
valueerrno.EPIPE
, so that a Python script can catch it, if it so chooses - see Alex L.'s answer for how to do that.If a Python script does not catch it, Python outputs error message
IOError: [Errno 32] Broken pipe
and terminates the script with exit code1
- this is the symptom the OP saw.In many cases this is more disruptive than helpful, so reverting to the default behavior is desirable:
Using the
signal
module allows just that, as stated in akhan's answer;signal.signal()
takes a signal to handle as the 1st argument and a handler as the 2nd; special handler valueSIG_DFL
represents the system's default behavior:from signal import signal, SIGPIPE, SIG_DFL signal(SIGPIPE, SIG_DFL)
I haven't reproduced the issue, but perhaps this method would solve it: (writing line by line to stdout
rather than using print
)
import sys
with open('a.txt', 'r') as f1:
for line in f1:
sys.stdout.write(line)
You could catch the broken pipe? This writes the file to stdout
line by line until the pipe is closed.
import sys, errno
try:
with open('a.txt', 'r') as f1:
for line in f1:
sys.stdout.write(line)
except IOError as e:
if e.errno == errno.EPIPE:
# Handle error
You also need to make sure that othercommand
is reading from the pipe before it gets too big - https://unix.stackexchange.com/questions/11946/how-big-is-the-pipe-buffer