好的,所以 pecl ssh2 应该是 libssh2 的包装器。libssh2 有 libssh2_channel_get_exit_status。有什么方法可以获取这些信息吗?
我需要:
-STDOUT
-STDERR
-EXIT 状态
我得到了除了退出状态之外的所有东西。当 ssh 启动时,很多人都在使用 phplibsec,但我看不出有任何方法可以从中获得 stderr 或通道退出状态:/ 有没有人能够获得这三个?
所以,第一件事是:
不,他们没有实现 libssh2_channel_get_exit_status。为什么?超越我。
这是 id 所做的:
$command .= ';echo -e "\n$?"'
我填了一个换行符和 $ 的回声?到我执行的每个命令的末尾。朗格?是的。但似乎效果还不错。然后我将其拉入 $returnValue 并从标准输出的末尾删除所有换行符。也许有一天会支持获取频道的退出状态,几年后它将在发行版存储库中。目前,这已经足够好了。当您运行 30 多个远程命令来填充复杂的远程资源时,这比为每个命令设置和拆除 ssh 会话要好得多。
我试图进一步改进 Rapzid 的回答。出于我的目的,我将 ssh2 包装在一个 php 对象中并实现了这两个功能。它允许我使用理智的异常捕获来处理 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 );
}