From: Alfredo Deza Date: Tue, 28 Oct 2014 14:26:07 +0000 (-0400) Subject: be faithful about stderr and stdout remote output order X-Git-Tag: 0.0.23~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=af83c400bf186b4c6b666979f638f1112940f6b1;p=remoto.git be faithful about stderr and stdout remote output order Fixes #8. --- diff --git a/remoto/process.py b/remoto/process.py index 41446f7..f2445a5 100644 --- a/remoto/process.py +++ b/remoto/process.py @@ -6,6 +6,7 @@ from .util import admin_command, RemoteError def _remote_run(channel, cmd, **kw): import subprocess import sys + from select import select stop_on_nonzero = kw.pop('stop_on_nonzero', True) process = subprocess.Popen( @@ -16,28 +17,34 @@ def _remote_run(channel, cmd, **kw): **kw ) - if process.stdout: - while True: - out = process.stdout.readline() - if out == '' and process.poll() is not None: - break - if out != '': - channel.send({'debug': out}) - sys.stdout.flush() - - if process.stderr: - while True: - err = process.stderr.readline() - if err == '' and process.poll() is not None: - break - if err != '': - channel.send({'warning': err}) - sys.stderr.flush() + while True: + reads, _, _ = select( + [process.stdout.fileno(), process.stderr.fileno()], + [], [] + ) + + for descriptor in reads: + if descriptor == process.stdout.fileno(): + read = process.stdout.readline() + if read: + channel.send({'debug': read}) + sys.stdout.flush() + + if descriptor == process.stderr.fileno(): + read = process.stderr.readline() + if read: + channel.send({'warning': read}) + sys.stderr.flush() + + if process.poll() is not None: + break returncode = process.wait() if returncode != 0: if stop_on_nonzero: - raise RuntimeError("command returned non-zero exit status: %s" % returncode) + raise RuntimeError( + "command returned non-zero exit status: %s" % returncode + ) else: channel.send({'warning': "command returned non-zero exit status: %s" % returncode})