如果你用git来管理web文件,那么如果你在本地修改文件后,需要gitadd/commit/push将代码提交到版本仓库,然后到服务器上执行git pull来更新文件。如果你是自建的仓库,那么你可以通过post-receive的hooks来触发脚本自动pull。但是事实上,我们通常是通过第三方的git仓库来管理项目的,如利用gitlab自建的仓库或第三方的github等。这样就无法利用post-receive钩子了。

以本人为例,我用的是coding.net的第三方仓库,每次修改提交后,还得去服务端pull,非常麻烦。一般第三方的仓库也提供了hooks,就是让你填一个url,当你执行了指定的操作后,它会自动向你填写的url发送请求,你只要在接收到这个请求后,执行相应的操作即可。本人之前是用php接收这个请求,然后通过php system函数来执行git pull,但是很麻烦,首先system是个危险函数,一般的服务器都禁止了,而且system执行git pull还涉及到一个权限的问题,需要设置sudo免密码。详见这里http://stackoverflow.com/questions/3173201/sudo-in-php-exec

上述的方法并不好用,用了几次后,我就不再用了。根据解耦的思路,如果我通过php来修改一个指定的文件,后台脚本通过定期扫描这个文件,如果这个文件有变化,则执行shell来gitpull是不是就行了呢?答案是可以得,但是,crontab的最低时间间隔是1分钟,所以要想实时监控文件变化,必须后台运行常驻脚本,这个脚本可以用python或node.js实现,但是略感复杂。偶然间,本人找到了inotify-tools.通过它来监控指定文件的变化实现自动pull。

inotify-tools可以在这里下载https://github.com/rvoicilas/inotify-tools

下载完了进入源目录,执行:

./autogen.sh

Clipboard Image.png

因为我的服务器没有安装libtool,直接用Yum命令安装即可

yum install libtool

完了继续安装:

./autogen.sh
.configure prefix=/usr/local/Inotify-tools
make 
make install
ln -s /usr/local/Inotify-tools/bin/inotifywait /usr/local/bininotifywait/

我们写个脚本监控/tmp/modify/目录

#!/bin/bash
WAIT_DIR=${1-/tmp/modify/}
/usr/local/inotify-tools/bin/inotifywait -qme attrib,modify,move,create,delete $WAIT_DIR --format '"%w" "%f" "%e" "%T"' --timefmt='%F_%T' \
        | while read DIR FILE EVENT TIME ;do

       # echo $DIR $FILE $EVENT $TIME
        eval "str=${FILE}"
        dir="/var/wwwroot/${str}/html/"
        cd $dir
        git pull
done

我们通过一个php文件,向/tmp/motify写入执行文件即可,本人的php是向/tmp/motify目录下的www.tiyee.net文件写入了时间戳触发的inotify脚本。

然后我们让监控脚本后台运行即可

 nohup /var/scripts/inotify.sh  > /var/scripts/logs/git.log 2>&1 &