From 951c8a5d27da586800f4b1eb9dc62cf553e17a23 Mon Sep 17 00:00:00 2001 From: Chris Lamb Date: Thu, 3 Mar 2016 19:16:58 +0000 Subject: [PATCH 1/2] Alias fileobj. --- lib/ansible/utils/display.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/ansible/utils/display.py b/lib/ansible/utils/display.py index 296a7b8180..0031e2c369 100644 --- a/lib/ansible/utils/display.py +++ b/lib/ansible/utils/display.py @@ -129,11 +129,12 @@ class Display: msg2 = to_unicode(msg2, self._output_encoding(stderr=stderr)) if not stderr: - sys.stdout.write(msg2) - sys.stdout.flush() + fileobj = sys.stdout else: - sys.stderr.write(msg2) - sys.stderr.flush() + fileobj = sys.stderr + + fileobj.write(msg2) + fileobj.flush() if logger and not screen_only: msg2 = nocolor.lstrip(u'\n') From eb1141ee799fd8da80052c2e9d5722afab9f1682 Mon Sep 17 00:00:00 2001 From: Chris Lamb Date: Thu, 3 Mar 2016 19:21:06 +0000 Subject: [PATCH 2/2] 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 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 --- lib/ansible/utils/display.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/ansible/utils/display.py b/lib/ansible/utils/display.py index 0031e2c369..5d056e5d22 100644 --- a/lib/ansible/utils/display.py +++ b/lib/ansible/utils/display.py @@ -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')