我有一个远程添加的文件(file.txt)。从SSH,我可以调用tail -f file.txt
,它将显示文件的更新内容。我希望能够对此文件进行阻止调用,该文件将返回最后一行。汇集循环根本不是一个选项。这就是我想要的:
$cmd = "tail -f file.txt";
$str = exec($cmd);
此代码的问题是tail
永远不会返回。是否有任何类型的尾部包装函数,一旦它返回内容就会杀死它?有没有更好的方法以低开销的方式做到这一点?
答案 0 :(得分:1)
我发现的唯一解决方案有点脏:
<?php
$descriptorspec = array(
0 => array("pipe", "r"), // stdin
1 => array("pipe", "w"), // stdout
2 => array("pipe", "w") // stderr
);
$process = proc_open('tail -f -n 0 /tmp/file.txt',$descriptorspec,$pipes);
fclose($pipes[0]);
stream_set_blocking($pipes[1],1);
$read = fgets($pipes[1]);
fclose($pipes[1]);
fclose($pipes[2]);
//if I try to call proc_close($process); here, it fails / hangs untill a second line is
//passed to the file. Hence an inelegant kill in the next 2 line:
$status = proc_get_status($process);
exec('kill '.$status['pid']);
proc_close($process);
echo $read;
答案 1 :(得分:0)
tail -n 1 file.txt
将始终返回文件中的最后一行,但我几乎可以肯定你想要的是让PHP知道file.txt何时有一个新行并显示它,所有这些都没有轮询在循环中。
如果它将检查新内容,无论如何都需要一个长时间运行的进程,无论是使用检查file modification time的轮询循环还是与其他地方保存的最后修改时间或其他任何方式进行比较。
你甚至可以通过cron运行php进行检查,如果你不想在php循环中运行(可能是最好的),或者通过执行循环的shell脚本并在需要时调用php文件次1分钟的跑步是cron的限制。
另一个想法,虽然我没有尝试过,但是要在非阻塞流中打开文件,然后使用相当高效的stream_select
让系统轮询更改。