2012-05-07 24 views
5

Ok, do đó, pecl ssh2 được cho là một trình bao bọc cho libssh2. libssh2 có libssh2_channel_get_exit_status. Có cách nào để có được thông tin này không?Trạng thái thoát kênh ssh2_exec của PHP?

TÔI CÓ CẦN:
-STDOUT
-STDERR
-EXIT TÌNH TRẠNG

tôi nhận được tất cả nhưng trạng thái thoát. Rất nhiều người ném xung quanh phplibsec khi ssh được đưa lên, nhưng tôi thấy không có cách nào để có được stderr hoặc tình trạng thoát kênh ra khỏi đó, hoặc:/Có ai đã có thể nhận được cả ba?

Trả lời

6

Vì vậy, điều đầu tiên là:
KHÔNG, chúng không triển khai libssh2_channel_get_exit_status. Tại sao? Ngoài tôi.

Đây là những gì id đã làm:

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

tôi nhồi nhét một dòng mới và tiếng vang của $? vào cuối mỗi lệnh tôi thực hiện. Rangy? Vâng. Nhưng có vẻ như nó đã hoạt động khá tốt. Sau đó tôi kéo nó ra thành $ returnValue và loại bỏ tất cả các dòng mới khỏi phần cuối của stdout. Có lẽ một ngày nào đó, trạng thái thoát của kênh sẽ được hỗ trợ và một vài năm sau đó, trạng thái thoát của kênh sẽ nằm trong bản phân phối. Bây giờ, điều này đã đủ tốt rồi. Khi bạn chạy hơn 30 lệnh từ xa để cư trú các tài nguyên từ xa phức tạp, điều này là tốt hơn nhiều so với việc thiết lập và xé xuống phiên ssh cho mỗi lệnh.

+1

Nếu lệnh là 'thoát 1', thì tiếng vọng sẽ không được chạy. '$ command = '('. $ command. '); echo -e" \ n $? "'' có thể tốt hơn. – Jesse

5

Tôi đã cố gắng cải thiện câu trả lời của Rapzid thêm một chút. Đối với mục tiêu của tôi, tôi bọc ssh2 trong một đối tượng php và thực hiện hai chức năng này. Nó cho phép tôi xử lý các lỗi ssh bằng cách sử dụng ngoại lệ sane.

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); 
}