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>
This commit is contained in:
Chris Lamb 2016-03-03 19:21:06 +00:00
parent 951c8a5d27
commit eb1141ee79

View file

@ -28,6 +28,7 @@ import time
import locale
import logging
import getpass
import errno
from struct import unpack, pack
from termios import TIOCGWINSZ
from multiprocessing import Lock
@ -134,7 +135,14 @@ class Display:
fileobj = sys.stderr
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:
msg2 = nocolor.lstrip(u'\n')