From dc9f3daf8dbb8ae352ae37cabd40a817eb115f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gildas=20Qu=C3=A9m=C3=A9ner?= Date: Tue, 17 Mar 2015 16:56:29 +0100 Subject: [PATCH] Rely on last command exit status to raise error Some tools like composer write human-related non-error messages to stderr, thus it's not safe to rely on stderr to decide if the command failed. More info: - https://github.com/composer/composer/issues/3795#issuecomment-76401013 - https://github.com/composer/composer/issues/1905#issuecomment-41631659 - https://github.com/composer/composer/pull/3715#issuecomment-73271923 --- src/Ssh/Exec.php | 13 +++++++++---- tests/Ssh/FunctionalTests/ExecTest.php | 6 +++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/Ssh/Exec.php b/src/Ssh/Exec.php index 82032ec..f951d37 100644 --- a/src/Ssh/Exec.php +++ b/src/Ssh/Exec.php @@ -9,6 +9,7 @@ * * @author Cam Spiers * @author Greg Militello + * @author Gildas Quéméner */ class Exec extends Subsystem { @@ -19,14 +20,18 @@ protected function createResource() public function run($cmd, $pty = null, array $env = array(), $width = 80, $height = 25, $width_height_type = SSH2_TERM_UNIT_CHARS) { + $cmd .= ';echo -ne "[return_code:$?]"'; $stdout = ssh2_exec($this->getResource(), $cmd, $pty, $env, $width, $height, $width_height_type); $stderr = ssh2_fetch_stream($stdout, SSH2_STREAM_STDERR); stream_set_blocking($stderr, true); stream_set_blocking($stdout, true); - $error = stream_get_contents($stderr); - if ($error !== '') { - throw new RuntimeException($error); + + $output = stream_get_contents($stdout); + preg_match('/\[return_code:(.*?)\]/', $output, $match); + if ((int) $match[1] !== 0) { + throw new RuntimeException(stream_get_contents($stderr), (int) $match[1]); } - return stream_get_contents($stdout); + + return preg_replace('/\[return_code:(.*?)\]/', '', $output); } } diff --git a/tests/Ssh/FunctionalTests/ExecTest.php b/tests/Ssh/FunctionalTests/ExecTest.php index aa6f162..3d5bd2d 100644 --- a/tests/Ssh/FunctionalTests/ExecTest.php +++ b/tests/Ssh/FunctionalTests/ExecTest.php @@ -45,7 +45,7 @@ public function testExecuteMultilineOutput() } /** - * @expectedException \RuntimeException MessageOnStdErr + * @expectedException \RuntimeException */ public function testExecuteErrorOutput() { @@ -54,9 +54,9 @@ public function testExecuteErrorOutput() $session = new Session($configuration, $authentication); $exec = $session->getExec(); - $output = $exec->run('echo "MessageOnStdErr" > /dev/stderr'); + $output = $exec->run('false'); $this->assertEquals('', trim($output)); } } - \ No newline at end of file +