This PHP snippet should execute a simple command via SSH (stripped down to minimal working example):
$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);
}
Works great as long as there is any output to stdout. However, if stdout remains empty, the loop turns into an endless loop.
$stdout = ssh2_exec($sshconn, 'echo hello >&2');
How do I read the stdout properly if
stream_get_contents
or the like). Addendum: My real world code that hangs executes mysqldump
with an unknown parameter. Obviously, echo -n >&2
works as expected, although its stdout is also empty.
If anyone stumbles upon this too: stderr has to be read too.
$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);
}
The disadvantage of this is that the SSH connection is no longer usable afterwards (a further ssh2_exec
cannot be executed).
A possible solution is to keep both streams blocking and read stdout and stderr non-interleaved:
$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);
I invite anyone who knows how to have the streams interleaved and keep the SSH connection usable to post another answer.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.