2010-10-16 57 views
0

我有一个远程添加的文件(file.txt)。从SSH,我可以拨打tail -f file.txt这将显示文件的更新内容。我想能够阻止对该文件的调用,它将返回最后附加的行。池化循环根本不是一种选择。这里是想什么我:PHP - 阻止文件读取

$cmd = "tail -f file.txt"; 
$str = exec($cmd); 

这段代码的问题是,tail将一去不复返。是否有任何类型的尾巴包装功能,一旦它返回内容就会杀死它?有没有更好的方法,以低花销的方式做到这一点?

+0

用'tail'的问题是,它并没有在最后发送一个新行...你永远不知道当行已经结束直到第二行被附加到文件。另外,你知道'tail -f'本身只是循环,默认间隔为1秒? – Wrikken 2010-10-16 22:37:31

+0

更正,换行符在那里,似乎是另一个问题... – Wrikken 2010-10-16 23:02:04

回答

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; 
+0

我想我需要把它折成包装功能,但这看起来像解决方案。我觉得这可能会更多的投票循环。但这是另一个问题。 – psayre23 2010-10-17 00:16:04

0

tail -n 1 file.txt将始终返回给你文件中的最后一行,但我几乎可以肯定你想要的是让PHP知道什么时候file.txt有一个新行,并显示它,所有都没有循环轮询。

无论如何,您需要一个长时间运行的进程,如果它将检查新内容,是否使用轮询循环来检查file modification time,并与其他地方保存的最后修改时间进行比较或以其他方式进行比较。

你甚至可以通过cron运行php来做检查,如果你不想让它运行在一个php循环中(可能是最好的),或者通过一个shell脚本执行循环并调用php文件需要小于1分钟的运行,这是cron的限制。

另一个想法,虽然我没有尝试过,但会打开非阻塞流中的文件,然后使用相当有效的stream_select让系统轮询更改。

+0

从我读过的内容来看,它看起来像'stream_select'不会在读取EOF(文件将有)时阻塞。尾巴完全符合我的要求,除非文件更改后不会退出。 – psayre23 2010-10-16 22:01:26