2012-05-07 4 views
5

Ok, quindi pecl ssh2 è presumibilmente un wrapper per libssh2. libssh2 ha libssh2_channel_get_exit_status. C'è qualche modo per ottenere queste informazioni?stato di uscita del canale ssh2_exec di PHP?

ho bisogno:
-STDOUT
-STDERR
-EXIT STATO

ho tutti, ma stato di uscita. Un sacco di gente gira intorno a phplibsec quando ssh viene richiamato, ma non vedo alcun modo di ottenere stderr o lo stato di uscita del canale da quello:/Qualcuno è riuscito a ottenere tutti e tre?

risposta

6

Quindi, la prima cosa è la prima:
NO, non hanno implementato libssh2_channel_get_exit_status. Perché? Al di là di me.

Ecco cosa ha fatto id:

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

ho stipare un ritorno a capo e eco di $? alla fine di ogni comando che eseguo. Longilineo? Sì. Ma sembra che abbia funzionato piuttosto bene. Quindi lo spengo in $ returnValue e spoglio tutte le newline dalla fine dello stdout. Forse un giorno verrà supportato lo stato di uscita del canale, e qualche anno dopo sarà nei repository di distribuzione. Per ora, questo è stato abbastanza buono. Quando esegui più di 30 comandi remoti per popolare complesse risorse remote, questo è molto, molto meglio che impostare e abbattere la sessione ssh per ogni comando.

+1

Se il comando è 'exit 1', l'eco non verrà eseguito. '$ command = '('. $ command. '); echo -e" \ n $? "'' potrebbe essere migliore. – Jesse

5

Ho cercato di migliorare la risposta di Rapzid un po 'di più. Per il mio scopo ho avvolto ssh2 in un oggetto php e ho implementato queste due funzioni. Mi permette di gestire gli errori ssh usando sane eccezioni di 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); 
}