2012-05-07 56 views
5

好吧,所以pecl ssh2被認爲是libssh2的包裝。 libssh2具有libssh2_channel_get_exit_status。有什麼方法可以獲取這些信息嗎?PHP ssh2_exec通道退出狀態?

我需要:
-stdout
-STDERR
-exit狀態

我得到的所有,但退出狀態。當ssh出現時,很多人都會拋出phplibsec,但是我看不出任何方式讓stderr或者頻道退出狀態退出:/有沒有人能夠獲得這三個?

回答

6

所以,第一件事是第一件事:
不,他們沒有實現libssh2_channel_get_exit_status。爲什麼?超越我。

這裏是ID做:

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

我補習班的$換行和回聲?到我執行的每個命令的末尾。瘦長?是。但它看起來工作得很好。然後我把它放到$ returnValue中,並將所有新行從標準輸出結束。也許有一天會獲得渠道的退出狀態,幾年之後它將在發行版中發佈。現在,這已經足夠好了。當您運行30+個遠程命令來填充複雜的遠程資源時,這比爲每個命令設置和拆除ssh會話要好得多。

+1

如果命令是'exit 1',回聲將不會運行。 '$ command ='('。$ command。'); echo -e「\ n $?」「''可能會更好。 – Jesse

5

我試圖改進Rapzid的答案更多一點。爲了我的目的,我在一個php對象中包裝了ssh2並實現了這兩個函數。它允許我使用正常的異常捕獲來處理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); 
}