Ignore EPIPE to avoid tracebacks when piping output to other commands

For example:

  $ ansible web --list-hosts | head -n1
  hosts (7):
  ERROR! Unexpected Exception: [Errno 32] Broken pipe
  Traceback (most recent call last):
    File "/home/lamby/git/private/lamby-ansible2/.venv/bin/ansible", line 114, in <module>
      display.display("to see the full traceback, use -vvv")
    File "/home/lamby/git/private/lamby-ansible2/.venv/local/lib/python2.7/site-packages/ansible/utils/display.py", line 133, in display
      sys.stdout.flush()
  IOError: [Errno 32] Broken pipe

Such a pipe target will close up shop early when its seen enough input,
causing ansible to print an ugly traceback.

Signed-off-by: Chris Lamb <chris@chris-lamb.co.uk>
pull/14774/head
Chris Lamb 9 years ago
parent 951c8a5d27
commit eb1141ee79

@ -28,6 +28,7 @@ import time
import locale import locale
import logging import logging
import getpass import getpass
import errno
from struct import unpack, pack from struct import unpack, pack
from termios import TIOCGWINSZ from termios import TIOCGWINSZ
from multiprocessing import Lock from multiprocessing import Lock
@ -134,7 +135,14 @@ class Display:
fileobj = sys.stderr fileobj = sys.stderr
fileobj.write(msg2) fileobj.write(msg2)
fileobj.flush()
try:
fileobj.flush()
except IOError as e:
# Ignore EPIPE in case fileobj has been prematurely closed, eg.
# when piping to "head -n1"
if e.errno != errno.EPIPE:
raise
if logger and not screen_only: if logger and not screen_only:
msg2 = nocolor.lstrip(u'\n') msg2 = nocolor.lstrip(u'\n')

Loading…
Cancel
Save