文件監控同步工具
引言
最近開發中遇到了一個問題,多個人使用同一個測試機,又是同一時間開發
,這樣就不能用git去更新代碼了,你要更新了代碼別人的功能就被你覆蓋了,
而一個取而代之的方法是通過rz
同步代碼文件,但這效率太低了,而且有可
能復制錯。
剛好之前做過fe開發,使用過百度的fisp,他的一個很重要的功能就是代碼發
布,於是沿着這個思路做出了這個工具。
如何監控文件
這里面最大的問題就是解決如何監控文件了,成百上千的文件、文件夾如何高效的監控,
我首先想到的還是php有沒有這樣的擴展,果不其然,找到了一個擴展類庫inotify
,
他有inotify_*()
5個函數,但是功能太弱了讓我大失所望,不能遞歸監控文
件夾,只能放棄使用php實現這個功能了。
沿着最開始的路線inotify
繼續探索,找到了linux下面的命令inotify-tools
,這個工具的功能就比較強大了,可以遞歸的監測文件夾及其子文件夾下面的文件
,於是就用shell實現了一個文件監控同步工具,預知具體細節,請繼續往下看,
問題一個個的解決
如何將文件保存到服務器
這個借鑒了fisp
的設計,在服務器上邊放一個接受文件的腳本,通過http的方式
將文件和要保存的地方發送給腳本,腳本進行保存,然后返回結果。
這個方法的優點很明顯:在互聯網公司,web服務一般都是有部署的,直接將腳本放上去
配置好目錄權限,就可以用了,簡單方便。
下面是服務端腳本的php代碼
<?php
@error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);
function mkdirs($path, $mod = 0777) {
if (is_dir($path)) {
return chmod($path, $mod);
} else {
$old = umask(0);
if(mkdir($path, $mod, true) && is_dir($path)){
umask($old);
return true;
} else {
umask($old);
}
}
return false;
}
if($_POST['to']){
$to = urldecode($_POST['to']);
if(is_dir($to) || $_FILES["file"]["error"] > 0){
header("Status: 500 Internal Server Error");
} else {
if(file_exists($to)){
unlink($to);
} else {
$dir = dirname($to);
if(!file_exists($dir)){
mkdirs($dir);
}
}
echo move_uploaded_file($_FILES["file"]["tmp_name"], $to) ? 0 : 1;
}
} else {
echo 'I\'m ready for that, you know.';
}
實現
監控也有了,上傳文件也有了,接下來就是具體的實現了:
- 首先就是解析運行腳本時候的參數,看看是否全量發布,是否監控,以及指定的服務器。
- 發布,發布這里原理很簡單,但實際實現的時候很麻煩,從監控的文件夾中最長匹配路徑,
搜索、拼接路徑,然后通過curl發布。 - 監控,監控用了管道命令,讓inotify-tools一直等待,有修改就傳遞給管道后面的程序,
管道后面的程序進行發布。
例子
在使用之前一定要確保安裝了inotify-tools
,監控依賴於這個軟件中inotifywait
功能,
一般可以直接使用yum install inotify-tools
安裝該軟件
我使用的一個小例子,首先必須能存在的是配置文件,config.sh
declare -A paths uploads
paths[actions]=/usr/local/nginx/html/actions/
paths[controllers]=/usr/local/nginx/html/controllers/
uploads[test1]="http://10.211.55.3/receiver.php"
uploads[test2]="http://10.211.55.3/receiver.php"
paths數組的鍵值定義了監控的文件夾名稱,uploads定義了發布的服務器名稱和地址
使用示例
命令 -d | --dest-server
是指定服務器名稱,后邊的發布就會發布到該服務器,-a | --all
會將所有的文件發布一邊,-w | --watch
會監控所有的文件,有改動進行發布,-h | --help
是查看幫助
github地址
watch-callback-file
歡迎一起改進優化