PHP实现linux命令tail -f

今天突然想到之前有人问过我的一个问题,如何通过PHP实现linux中的命令tail -f,这里就来分析实现下。

这个想一想也挺简单,通过一个循环检测文件,看文件的大小是否有变化,如果有变化,输出文件变化的部分,当然了这里面会有好多的细节,这里具体分析下。

如果初始文件太大或者改变内容太多

这个时候一下输出好多内容可能看不清,因此我这里设置了一个阈值8192,当内容长度超过这个阈值的时候,只输出最后面的8192个字节,这样就不会出现大面积的刷新导致看不清的问题。

如何检测文件大小的变化

这个问题是这个程序的核心,能不能成功,性能的好坏就靠这部分了。

我在这里的实现是下面这样:

  • 打开文件句柄$fp,这里要注意,这里的文件句柄全程需中只打开一次关闭一次,因此要将他放在循环的外面。
  • 初始化当前文件大小file_sizefile_size_new都为0。
    • 循环里面更新file_size_new文件大小,这里要注意,php中获取文件大小之前一定要运行函数clearstatcache(),清除文件状态缓存,否则获取文件大小可能会有偏差。
    • 计算add_size = file_size_new - file_size,看文件大小是否有变化,如果有变化,将文件指针移动到指定位置,然后输出新加的内容,更新file_size值为new_file_size
    • usleep(50000),睡眠1/20秒。

代码实现

#!/usr/bin/env php
<?php
if(2 != count($argv)){
fwrite(
STDERR,
"调用格式错误!使用格式 ./tail filename".PHP_EOL
);
return 1;
} $file_name = $argv[1];
define("MAX_SHOW", 8192); $file_size = 0;
$file_size_new = 0;
$add_size = 0;
$ignore_size = 0;
$fp = fopen($file_name, "r");
while(1){
clearstatcache();
$file_size_new = filesize($file_name);
$add_size = $file_size_new - $file_size;
if($add_size > 0){
if($add_size > MAX_SHOW){
$ignore_size = $add_size - MAX_SHOW;
$add_size = MAX_SHOW;
fseek($fp, $file_size + $ignore_size);
}
fwrite(
STDOUT,
fread($fp, $add_size)
);
$file_size = $file_size_new;
}
usleep(50000);
} fclose($fp);

代码实现这里第一行的#!/usr/bin/env php 是告诉可执行文件,可执行文件php在系统PATH中查找,这样的好处就是移植性好。

2016-02-22 11:28:51改进

查了PHP官方手册,fseek函数这里可以改进改进,这个函数还接受第三个参数,表示偏移指针的类型,默认是SEEK_SET,从开始偏移,还可以设置为SEEK_CUR,表示从当前位置偏移,因此这里改为fseek($fp, $ignore_size, $ignore_size);

下面是结果

PHP实现linux命令tail -f的更多相关文章

  1. Linux 系统中如何查看日志 (常用命令) tail -f

    Linux 系统中如何查看日志 (常用命令)  tail -f 日志文件 日 志 文 件 说 明 /var/log/message 系统启动后的信息和错误日志,是Red Hat Linux中最常用的日 ...

  2. linux之tail -F命令异常file truncated

    使用tail -F收集日志时,经常报出file truncated, 导致日志又重新读取.tail: `test.out' has appeared;  following end of new fi ...

  3. 菜鸟学Linux命令:tail命令 查看日志

    tail 命令用于显示指定文件末尾内容,不指定文件时,作为输入信息进行处理. tail命令常用来查看日志文件.使用tail命令的-f选项可以方便的查阅正在改变的日志文件,tail -f filenam ...

  4. Linux 命令 - tail: 打印文件的结尾部分

    命令格式 tail [OPTION]... [FILE]... 命令参数 -c, --bytes=[-]K 显示每个文件的后 K 字节内容.-n +K 则表示从第 K 字节开始输出. -f, --fo ...

  5. 每天学点linux命令--tail,cut,sort,uniq

    tail 命令从指定点开始将文件写到标准输出.使用tail命令的-f选项可以方便的查阅正在改变的日志文件,tail -f filename会把filename里最尾部的内容显示在屏幕上,并且不但刷新, ...

  6. 转:linux命令: tail ,head 显示文件某行内容 与sed在线编辑器

    linux 如何显示一个文件的某几行(中间几行) 转:http://www.cnblogs.com/xianghang123/archive/2011/08/03/2125977.html http: ...

  7. Linux命令: ls -F

    ls -F 列出目录中的文件 -F参数使得ls命令显示的目录文件名之后加一个斜线(“/”)字符 文件后面的星号("*")表示这是一个可执行程序

  8. 每日linux命令学习-head命令和tail命令

    本节主要学习了linux文件浏览的相关命令,包括cat.less.more.read.tail等,由于本人经常使用cat.less.more命令,已经较为熟悉,所以本节重点学习head命令和tail命 ...

  9. windows下使用tail -f 命令查看实时日志

    经常在linux后台进行日志分析的同学对tail -f 这个命令肯定不陌生了,监控实时系统日志简直不要太方便.但是作为一个自动化测试工程师,我们的代码实际上在本地跑就够了,不需要部署,但是window ...

随机推荐

  1. js自动完成

    源代码来自于: http://down.51cto.com/data/921955  我做了一下修改. 要做一个自动完成的功能,又不想依赖一大堆的js脚本库,我要的是定制的,代码尽可能简洁,方便修改和 ...

  2. 聊下git pull --rebase

    有一种场景是经常发生的. 大家都基于develop拉出分支进行并行开发,这里的分支可能是多到数十个.然后彼此在进行自己的逻辑编写,时间可能需要几天或者几周.在这期间你可能需要时不时的需要pull下远程 ...

  3. 从零自学Hadoop(07):Eclipse插件

    阅读目录 序 Eclipse Eclipse插件 新建插件项目 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephisto)写 ...

  4. mongo学习笔记(一):增删改查

    安装:我是按这篇来弄的 一.Insert 1.db.person.insert({"name":"jack","age":20}) 2.va ...

  5. ubuntu su sudo sudo–i 区别

    sudo : 暂时切换到超级用户模式以执行超级用户权限,提示输入密码时该密码为当前用户的密码,而不是超级账户的密码.不过有时间限制,Ubuntu默认为一次时长15分钟. su : 切换到某某用户模式, ...

  6. extjs学习资料

    ExtJs 入门教程 1.Extjs5.1.0教程云盘地址 http://pan.baidu.com/s/1qYhHiEw 2.Extjs3.x如下:   ExtJs 入门教程一[学习方法] ExtJ ...

  7. Linux一些经典书籍

    一.linux之路 1.入门篇 <LINUX权威指南>书不错,写的很全面也比较广,涉及的不深,做为入门书籍不错,可以比较全面的了解linux .另外比较热门的也可以看看<鸟哥的私房菜 ...

  8. 【Windows编程】系列第十一篇:多文档界面框架

    前面我们所举的例子中都是单文档界面框架,也就是说这个窗口里面的客户区就是一个文档界面,可以编写程序在里面输入或者绘制文本和图形输出,但是不能有出现多个文档的情况.比如下面的UltraEdit就是一个典 ...

  9. EF optimize the perfermance

          参考 Three steps for fast entityframework 6.1 code-first startup performance Managing DbContext ...

  10. dpctl 工具使用

    一.在建立Mininet的时候,需要设置listenPort,这样可以在其它命令行里设置flow net = Mininet( topo=topo, listenPort=6634 ) 二.常见用法m ...