我有一个远程添加的文件(file.txt)。从SSH,我可以拨打tail -f file.txt
这将显示文件的更新内容。我想能够阻止对该文件的调用,它将返回最后附加的行。池化循环根本不是一种选择。这里是想什么我:PHP - 阻止文件读取
$cmd = "tail -f file.txt";
$str = exec($cmd);
这段代码的问题是,tail
将一去不复返。是否有任何类型的尾巴包装功能,一旦它返回内容就会杀死它?有没有更好的方法,以低花销的方式做到这一点?
我有一个远程添加的文件(file.txt)。从SSH,我可以拨打tail -f file.txt
这将显示文件的更新内容。我想能够阻止对该文件的调用,它将返回最后附加的行。池化循环根本不是一种选择。这里是想什么我:PHP - 阻止文件读取
$cmd = "tail -f file.txt";
$str = exec($cmd);
这段代码的问题是,tail
将一去不复返。是否有任何类型的尾巴包装功能,一旦它返回内容就会杀死它?有没有更好的方法,以低花销的方式做到这一点?
我发现的唯一的解决办法是有点脏:
<?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;
我想我需要把它折成包装功能,但这看起来像解决方案。我觉得这可能会更多的投票循环。但这是另一个问题。 – psayre23 2010-10-17 00:16:04
tail -n 1 file.txt
将始终返回给你文件中的最后一行,但我几乎可以肯定你想要的是让PHP知道什么时候file.txt有一个新行,并显示它,所有都没有循环轮询。
无论如何,您需要一个长时间运行的进程,如果它将检查新内容,是否使用轮询循环来检查file modification time,并与其他地方保存的最后修改时间进行比较或以其他方式进行比较。
你甚至可以通过cron运行php来做检查,如果你不想让它运行在一个php循环中(可能是最好的),或者通过一个shell脚本执行循环并调用php文件需要小于1分钟的运行,这是cron的限制。
另一个想法,虽然我没有尝试过,但会打开非阻塞流中的文件,然后使用相当有效的stream_select
让系统轮询更改。
从我读过的内容来看,它看起来像'stream_select'不会在读取EOF(文件将有)时阻塞。尾巴完全符合我的要求,除非文件更改后不会退出。 – psayre23 2010-10-16 22:01:26
用'tail'的问题是,它并没有在最后发送一个新行...你永远不知道当行已经结束直到第二行被附加到文件。另外,你知道'tail -f'本身只是循环,默认间隔为1秒? – Wrikken 2010-10-16 22:37:31
更正,换行符在那里,似乎是另一个问题... – Wrikken 2010-10-16 23:02:04