2012-05-07 3 views
5

좋아, 그럼 pecl ssh2는 아마도 libssh2에 대한 래퍼입니다. libssh2에는 libssh2_channel_get_exit_status가 있습니다. 이 정보를 얻을 수있는 방법이 있습니까?PHP ssh2_exec 채널 종료 상태?

내가이 필요합니다
-STDOUT
-STDERR
-exit 상태

나는 모든하지만 종료 상태를 얻는다. 많은 사람들이 ssh가 기동 할 때 phplibsec을 던지기는하지만, stderr 나 채널 종료 상태를 알 수있는 방법이 없다는 것을 알았습니다.// 누군가 3 가지를 모두 얻을 수 있었습니까?

답변

6

첫 번째 것은 첫 번째입니다.
아니요, 그들은 libssh2_channel_get_exit_status를 구현하지 않았습니다. 왜? 나를 넘어.

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


내가 $의 줄 바꿈과 에코를 밀어 넣는 : 여기

이 무슨 짓을했는지 ID입니다? 내가 명령 한 모든 명령의 끝에 넓은? 예. 그러나 그것은 오히려 잘 진행된 것으로 보인다. 나는 그 다음 $ returnValue에 그것을 빼고 stdout의 끝에서 모든 줄 바꿈을 제거한다. 어쩌면 언젠가는 채널의 종료 상태가 지원 될 것이고, 몇 년 후에는 배포판에 저장 될 것입니다. 당분간, 이것은 충분히 좋았습니다. 30 개 이상의 원격 명령을 실행하여 복잡한 원격 리소스를 채우는 경우 각 명령에 대한 ssh 세션을 설정 및 해제하는 것보다 훨씬 낫습니다.

+1

명령이 'exit 1'이면 에코가 실행되지 않습니다. '$ command = '('. $ command. '); echo -e "\ n $?"''더 좋을 수도 있습니다. – Jesse

5

나는 Rapzid의 답변을 좀더 개선하려고 노력했다. 내 목적을 위해 PHP 객체에 ssh2를 래핑하고이 두 함수를 구현했습니다. sane exception catch를 사용하여 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); 
}