PHP:通过使用proc_open(“ssh 主机名'tail -F ~somefile'”)死锁


PHP: Deadlock through using proc_open("ssh hostname 'tail -F ~somefile' ")

碰巧我需要通过 ssh 通过 php(使用 phpunit)跟踪文件状态。但是当我尝试启动此代码时:

$descriptorspec = array(
  0 => array('pipe', 'r'),
  1 => array('pipe', 'w'),
  2 => array('pipe', 'w'),
);
$cmd = "ssh hostname 'tail -F ~/test.file'";
$proc = proc_open($cmd, $descriptorspec, $pipes, null);
$str = fgets($pipes[1]);
echo $str;
if (!fclose($pipes[0])) {
  throw new Exception("Can't close pipe 0");
}
if (!fclose($pipes[1])) {
  throw new Exception("pipe 1");
}
if (!fclose($pipes[2])) {
  throw new Exception("pipe 2");
}
$res = proc_close($proc);

什么也没发生 - 没有输出,我猜死锁消失了:脚本没有退出。有什么想法吗?还是建议?

tail -F实际上并没有"结束" - 它只是在可用时不断转储输出。这可能是问题所在。它阻止了 fgets()。

我的建议:使用phpseclib,一个纯粹的PHP SSH2实现。

<?php
include('Net/SSH2.php');
$ssh = new Net_SSH2('www.domain.tld');
if (!$ssh->login('username', 'password')) {
    exit('Login Failed');
}
function packet_handler($str)
{
    echo $str;
}
$ssh->exec('tail -F ~/test.file', 'packet_handler');
?>

虽然看实施,但现在...它看起来也没有为您提供任何过早退出的机制。如果它像"如果packet_handler返回 false 则 exec() 停止运行"或其他东西,那就太好了。

我想你可以用->setTimeout()代替.