7

さて、pecl ssh2 はおそらく libssh2 のラッパーです。libssh2 には libssh2_channel_get_exit_status があります。この情報を取得する方法はありますか?

必要なもの:
-STDOUT
-STDERR -
終了ステータス

終了ステータス以外はすべて取得します。多くの人が ssh を立ち上げたときに phplibsec をいじくり回しますが、そこから stderr やチャネルの終了ステータスを取得する方法がわかりません:/ 3 つすべてを取得できた人はいますか?

4

2 に答える 2

10

したがって、最初に行うことは最初です。
いいえ、libssh2_channel_get_exit_statusを実装していません。なんで?私を超えて。

idが行ったことは次のとおりです。

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

改行と$のエコーを詰め込みますか?私が実行するすべてのコマンドの最後に。ランジー?はい。しかし、それはかなりうまくいったようです。次に、それを$ returnValueにプルし、stdoutの終わりからすべての改行を取り除きます。いつかチャネルの終了ステータスを取得することがサポートされ、数年後にはディストリビューションリポジトリに配置される可能性があります。今のところ、これで十分です。30以上のリモートコマンドを実行して複雑なリモートリソースにデータを入力する場合、これは、各コマンドのsshセッションを設定および破棄するよりもはるかに優れています。

于 2012-05-09T11:14:55.087 に答える
7

Rapzidの回答をもう少し改善しようとしました。私の目的のために、ssh2 を php オブジェクトでラップし、これら 2 つの関数を実装しました。これにより、適切な例外キャッチを使用して ssh エラーを処理できます。

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 );
}
于 2012-06-07T21:13:10.720 に答える