PHP ssh2_exec channel exit status?
Asked Answered
W

3

7

Ok, so pecl ssh2 is supposedly a wrapper for libssh2. libssh2 has libssh2_channel_get_exit_status. Is there ANY way to get this information?

I NEED:
-STDOUT
-STDERR
-EXIT STATUS

I get all but exit status. A lot of people throw around phplibsec when ssh is brought up, but I see no way of getting stderr or the channel exit status out of that either:/ Has anybody been able to get all three?

Westbrook answered 7/5, 2012 at 7:47 Comment(0)
W
11

So, first thing is first:
NO, they didn't implement libssh2_channel_get_exit_status. Why? Beyond me.

Here is what id did:

$command .= ';echo -e "\n$?"'

I cram a newline and echo of $? onto the end of every command I exec. Rangy? Yes. But it seems to have worked out rather well. I then pull that off into $returnValue and strip all the newlines off the end of stdout. Maybe someday getting the channel's exit status will be supported, and a few years after that it will be in the distro repos. For now, this has been good enough. When your running 30+ remote commands to populate complex remote resources, this is much, much better than setting up and tearing down the ssh session for each command.

Westbrook answered 9/5, 2012 at 11:14 Comment(1)
If the command is exit 1, the echo wont be run. $command = '(' . $command . ');echo -e "\n$?"' might be better.Solvent
M
7

I tried to improve upon Rapzid's answer a bit more. For my purposed I wrapped ssh2 in a php object and implemented these two functions. It allows me to handle the ssh errors using sane exception catching.

function exec( $command )
{
    $result = $this->rawExec( $command.';echo -en "\n$?"' );
    if( ! preg_match( "/^(.*)\n(0|-?[1-9][0-9]*)$/s", $result[0], $matches ) ) {
        throw new RuntimeException( "output didn't contain return status" );
    }
    if( $matches[2] !== "0" ) {
        throw new RuntimeException( $result[1], (int)$matches[2] );
    }
    return $matches[1];
}

function rawExec( $command )
{
    $stream = ssh2_exec( $this->_ssh2, $command );
    $error_stream = ssh2_fetch_stream( $stream, SSH2_STREAM_STDERR );
    stream_set_blocking( $stream, TRUE );
    stream_set_blocking( $error_stream, TRUE );
    $output = stream_get_contents( $stream );
    $error_output = stream_get_contents( $error_stream );
    fclose( $stream );
    fclose( $error_stream );
    return array( $output, $error_output );
}
Marris answered 7/6, 2012 at 21:13 Comment(0)
V
0

Since version 0.13 of the SSH2 PHP extension, you can use stream_get_meta_data() to retrieve the exit staus.

With the code of your example:

// $connection is a SSH2 connection created with ssh2_connect()
// $command is the command you want to execute
$stream = ssh2_exec($connection, $command);
$metadata = stream_get_meta_data($stream);
$exitCode = $metadata['exit_status'];
Vasques answered 21/9, 2023 at 15:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.