1

Happens that i need to track file status through ssh by php(using phpunit). But when i trying to launch this code:

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

nothing happens - no output, and i guess deadlock exucuted: script doesn't exit. Have any ideas? or suggestions?

1 Answers1

0

tail -F doesn't actually "end" - it just keeps dumping output as it becomes available. That's probably the problem. It's blocking on the fgets().

My recommendation: use phpseclib, a pure PHP SSH2 implementation. eg.

<?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');
?>

Although looking at the implementation, now... it doesn't look like it provides you with any mechanism to prematurely quit either. It'd be nice if it was like "if packet_handler returns false then exec() stops running" or something.

I guess in lieu of that you can use ->setTimeout().

neubert
  • 15,947
  • 24
  • 120
  • 212
  • ty for answer. I guess my fault was that im thinking that "proc_open" execute command with something like daemonizing this command. – user2968022 Nov 11 '13 at 10:12
  • For that you'd prob have to do something like `nohup`. But even then my expectation is that, with either OpenSSH or phpseclib, both would return immediately without giving you any sort of output. – neubert Nov 11 '13 at 14:53
  • dude stop posting this.. i've been googling for a solution and all i see your same exact stupid copied and pasted answer.. this doesn't work everywhere.. – I wrestled a bear once. Oct 22 '15 at 20:18
  • @Pamblam - dude you're commenting on a two year old post. What's next? Maybe you should go post in http://stackoverflow.com/q/9014164/569976 and tell me I should upgrade because the library I'm using is three and a half years out of date (which is coincidentally how old that post is) – neubert Oct 22 '15 at 20:33
  • @Pamblam - besides, my answers aren't preventing others from posting their own "better" answers. If you don't think a question has a satisfactory answer then you can offer a bounty on the question to draw attention to it and then award the bounty to that answer. – neubert Oct 22 '15 at 20:41
  • I'm not complaining because the post is 2 years old it's still a valid answer, works on php5, I'm complaining because you posted the exact same answer on every. Single. Relevant question I found in google. My problem is that my job uses a version of php that went extinct before the dinosaurs did and your answer is actually too modern. – I wrestled a bear once. Oct 22 '15 at 22:46
  • Sorry just blowing off steam – I wrestled a bear once. Oct 22 '15 at 22:47
  • Not to beat a dead horse or anything but FWIW phpseclib (the 1.0 branch) should work on PHP 4 if you use PHP_Compat. http://phpseclib.sourceforge.net/math/speed.phps provides an example of this. You'd also need to use the clone() and array_fill() functions from PHP_Compat but it should work. I'm guessing PHP 4 is what you're using? – neubert Oct 23 '15 at 13:11
  • thanks neubert, i actually fid get it working on our ancient servers with your answer. – I wrestled a bear once. Oct 23 '15 at 20:57