zoukankan      html  css  js  c++  java
  • linux文件文件夹递归监控

    引言

    今年(2016)年初来到A公司了,刚入职的时候比较缺前端fe,就过来顶了三个月,这段时间学到了好多前端开发的知识,这些都是题外话了。期间接触了一个很好用的前端自动化部署工具 —— fis,其中有个小功能特别好用,实时监控文件,然后同步到服务端,大大提高了开发的效率。之后转到后端,发现大家开发测试相同模块的时候经常会出现互相覆盖的情况,要么就一个个的复制文件到服务器上,效率非常低下,之前为这个也开发过一个纯shell版本的自动化监控同步工具文件同步监控工具后来发现纯shell版本的使用体验和扩展性能非常差,就开发了这篇文章所要介绍的php版本。

    这次开发了一个规范的php composer包,使用的时候直接require即可。

    实现

    php版本的实现沿用了shell版本的思想,通过管道命令传递shell命令的结果,然后对结果做各种处理,达到我们监控文件的目的。

    为了完成这个功能,首先要实现一个php版本的管道命令,这里我对resource popen ( string $command , string $mode )做了封装,可以通过很友好的处理命令的返回值。

    完成了上面的模块,接下来就是具体的实现了,实现这里有多重友好的方式,添加多路径递归监控、包含正则匹配、排除正则匹配。

    pipe的开发

    <?php
    /**
     * php对对popen的封装,通过回调的方式模拟管道命令
     *
     */
    namespace AizuyanPipe;
    class Pipe
    {
        /**
         * 要通过管道执行的命令
         */
        protected $command = "";
        /**
         * 回调函数,将管道数据传递给该函数
         */
        protected $callback = null;
        /**
         * 数据之间的分隔符
         */
        protected $delimiter = "
    ";
        /**
         * 设置命令
         *
         * @param cmd string 要运行的命令
         */
        public function setCmd($cmd)
        {
            $this->command = $cmd;
            return $this;
        }
        /**
         * 设置回调函数,处理管道输出的命令
         */
        public function setCallback(callable $cb)
        {
            $this->callback = $cb;
            return $this;
        }
        /**
         * 设置数据片段之间的分隔符
         */
        public function setDelimiter($delimiter)
        {
            $this->delimiter = $delimiter;
            return $this;
        }
        /**
         * 开始运行
         */
        public function run()
        {
            $fp = popen($this->command, "r");
            if (false === $fp) {
                throw new RuntimeException("popen execute command failed!");
            }
            $item = "";
            while (!feof($fp)) {
                $char = fgetc($fp);
                if ($this->delimiter == $char) {
                    call_user_func($this->callback, $item);
                    $item = "";
                } else {
                    $item .= $char;
                }
            }
            pclose($fp);
        }
    }
    

    下面是测试程序

    <?php
    include "vendor/autoload.php";
    $test = new RitoyanPipePipe();
    $test->setCmd("tail -f /root/t.txt")->setCallback(function($item){
            echo "获取内容:" . $item . "
    ";
    })->setDelimiter("
    ")->run();
    

    tail -f /root/t.txt这个shell命令的返回结果进行实时处理,setCallback(callable func)设置了回调函数,func的参数是shell命令的标准输出,setDelimiter($delimiter)设置了传入回调函数参数的分隔符,这样就可以很容易、很任性的将输出传递给回调函数了。

    inotify开发

    这部分代码就不提出来了,主要就是依赖上面的Pipe然后对inotifywait -mrq --format '%w,%e,%f'命令的输出做处理,正向逆向过滤,下面是对Inotify的调用

    <?php
    require "vendor/autoload.php";
    $obj = new AizuyanInotifyInotify();
    $obj->addExclude([
        "/swp$/",
        "/swpx$/",
        "/~$/",
        "/d$/",
        "/swx$/"
    ])->setCallback(function ($item){
        echo $item["event"] . " 文件 " . $item["file"] . "
    ";
    })->addPaths("/datas/git/")->start();
    

    这样运行之后,到我们修改/datas/git目录下的文件的时候会输出下面的内容,可以很方便的对修改文件做定制化的处理

    CREATE 文件 /datas/git/inotify/README.md
    MODIFY 文件 /datas/git/inotify/README.md
    MOVED_TO 文件 /datas/git/aizuyan/pinyin-1/README.md
    DELETE 文件 /datas/git/aizuyan/pinyin-1/LICENSE
    ......
    

    inotify-tools安装

    整个功能依赖于一个linux软件 —— inotify-tools
    centos安装yum install inotify-tools,或者通过源码直接安装(文档)尝试在OS中安装,发现失败了~

    如何使用

    我已经将他发布到了composer仓库中,可以轻松安装:
    composer require aizuyan/inotify,之后就可以像上面的例子一样使用了

    另外这是开发的两个组件的github地址:AizuyanPipePipeAizuyanInotifyInotify

  • 相关阅读:
    windows 按时自动化任务
    Linux libusb 安装及简单使用
    Linux 交换eth0和eth1
    I.MX6 GPS JNI HAL register init hacking
    I.MX6 Android mmm convenient to use
    I.MX6 GPS Android HAL Framework 调试
    Android GPS GPSBasics project hacking
    Python windows serial
    【JAVA】别特注意,POI中getLastRowNum() 和getLastCellNum()的区别
    freemarker跳出循环
  • 原文地址:https://www.cnblogs.com/iforever/p/6017262.html
Copyright © 2011-2022 走看看