簡體   English   中英

PHP ssh2_exec在空標准輸出上沒有功能

[英]PHP ssh2_exec no feof on empty stdout

這個PHP代碼段應該通過SSH執行一個簡單的命令(簡化為最小的工作示例):

$sshconn = ssh2_connect($HostAddr, 22);
ssh2_auth_pubkey_file($sshconn, $user, $sshkey . '.pub', $sshkey);
$stdout = ssh2_exec($sshconn, 'echo hello');
if ($stdout !== false)
{
    stream_set_blocking($stdout, true);
    while (!feof($stdout))
    {
        $proc_stdout = fgets($stdout, 3E6);
        if ($proc_stdout !== false) echo $proc_stdout;
    }
    fclose($stdout);
}

只要有任何輸出到stdout,效果就很好。 但是,如果stdout保持為空,則循環將變成一個無限循環。

$stdout = ssh2_exec($sshconn, 'echo hello >&2');

如果我如何正確讀取標准輸出

  • 標准輸出可能為空
  • 但是stdout可能也很大(幾個千兆字節,不可能通過一次調用stream_get_contents之類的東西而變成變量)。

附錄:我的現實世界代碼掛起執行帶有未知參數的mysqldump 顯然, echo -n >&2可以正常工作,盡管它的stdout也為空。

如果有人也偶然發現此內容:也必須閱讀stderr。

$sshconn = ssh2_connect($HostAddr, 22);
ssh2_auth_pubkey_file($sshconn, $user, $sshkey . '.pub', $sshkey);

$stdout = ssh2_exec($sshconn, 'echo Hello >&2');
if ($stdout !== false)
{
    $stderr = ssh2_fetch_stream($stdout, SSH2_STREAM_STDERR);
    stream_set_blocking($stdout, false);
    stream_set_blocking($stderr, false);
    while (!feof($stdout))
    {
            $proc_stdout = fgets($stdout, 3E6);
            if ($proc_stdout !== false) echo $proc_stdout;
            $proc_stderr = fgets($stderr, 3E6);
            if ($proc_stderr !== false) fwrite(STDERR, $stderr);
    }
    fclose($stdout); fclose($stderr);
}

這樣做的缺點是SSH連接以后將不再可用(無法再執行ssh2_exec )。

一個可能的解決方案是保持流都阻塞,並且不交錯讀取stdout和stderr:

$stdout = ssh2_exec($sshconn, 'echo Hello >&2');
$stderr = ssh2_fetch_stream($stdout, SSH2_STREAM_STDERR);
stream_set_blocking($stdout, true);
stream_set_blocking($stderr, true);
while ($content = fread($stdout, 3E6)) echo $content;
while ($content = fread($stderr, 3E6)) fwrite(STDERR, $content);

我邀請任何知道如何使流交錯並保持SSH連接可用的人來發布另一個答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM