由於每次前端同學的vue項目push到git後,都需要私下告訴我,然後我更新代碼並重新構建,嫌麻煩,但由於本地環境的ip非公網ip,webhook不可達,所以只能使用crontab定時拉取代碼,再配合inotifywait監聽文件變化,自動build構建代碼,遂寫此文記錄下inotifywait的安裝和基本使用,以便後續查閱。
一、inotifywait介紹
Inotify
一種強大的、細粒度的、異步文件系統監控機制,它滿足各種各樣的文件監控需要,可以監控文件系統的訪問屬性、讀寫屬性、權限屬性、刪除創建、移動等操作,也就是可以監控文件發生的一切變化。
inotify-tools
是一個C庫和一組命令行的工作,提供Linux下inotify的簡單接口。inotify-tools
安裝後會得到inotifywait
和inotifywatch
這兩條命令:
inotifywait
命令 可以用來收集有關文件訪問信息,Linux發行版一般沒有包括這個命令,需要安裝inotify-tools
,這個命令還需要將inotify支持編譯入Linux內核,好在大多數Linux發行版都在內核中啓用了inotify。inotifywatch
命令 用於收集關於被監視的文件系統的統計數據,包括每個 inotify 事件發生多少次。
此外,同類型工具還有fswatch等
//@Todo 同類工具選擇比較
二、安裝
2.1 開始之前需要檢測系統內核是否支持inotify
-
方式一:使用
uname -r
命令檢查Linux內核,如果低於2.6.13
,就需要重新編譯內核加入inotify的支持。 -
方式二:使用
ll /proc/sys/fs/inotify
命令,是否有以下三條信息輸出,如果沒有表示不支持。
$ ll /proc/sys/fs/inotify
total 0
-rw-r--r-- 1 root root 0 Jan 4 15:41 max_queued_events
-rw-r--r-- 1 root root 0 Jan 4 15:41 max_user_instances
-rw-r--r-- 1 root root 0 Jan 4 15:41 max_user_watches
2.2 安裝步驟
可直接使用Linux系統自帶的包管理工具進行安裝,也可以手動從源碼編譯安裝。
2.2.1 包管理工具進行安裝
以centos系統自帶等yum爲例
其他Linux發行版安裝方法可以參見:https://github.com/rvoicilas/inotify-tools/wiki#wiki-getting
$ yum search inotify-tools
$ yum info inotify-tools
$ sudo yum install inotify-tools
2.2.2 源碼編譯安裝
$ wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
$ tar zxf inotify-tools-3.14.tar.gz
$ cd inotify-tools-3.14/
$ ./configure && make && make install
如果遇到以下錯誤
inotifywait: error while loading shared libraries: libinotifytools.so.0: cannot open shared object file: No such file or directory
解決方法:
32位系統:ln -s /usr/local/lib/libinotifytools.so.0 /usr/lib/libinotifytools.so.0
64位系統:ln -s /usr/local/lib/libinotifytools.so.0 /usr/lib64/libinotifytools.so.0
三、inotifywait 基本使用
安裝完成後可簡單嘗試下,執行以下命令監聽log.txt文件
$ inotifywait -m log.txt
# 這裏 -m 參數指明持續監聽,不加的話會在一個事件後退出
Setting up watches.
Watches established.
# 此時持續監聽,有事件出發會輸出到屏幕
然後通過其他窗口執行以下命令向log.txt文件寫入內容
$ echo >> log.txt
可觀察到上一個屏幕輸出了,因爲監聽到了文件打開、修改、關閉的事件。
log.txt OPEN
log.txt MODIFY
log.txt CLOSE_WRITE,CLOSE
3.1、參數說明
3.1.1 常用參數
--timefmt 時間格式
%y年 %m月 %d日 %H小時 %M分鐘
--format 輸出格式
%T時間 %w路徑 %f文件名 %e狀態
-m 始終保持監聽狀態,默認觸發事件即退出
-r 遞歸查詢目錄
-q 減少不必要的輸出(只打印事件信息)
-e 定義監控的事件,可用參數:
open 打開文件
access 訪問文件
modify 修改文件
delete 刪除文件
create 新建文件
attrib 屬性變更
--exclude <pattern> 指定要排除監控的文件/目錄
3.1.2 全部參數
建議通過 man inotifywait
命令查看文檔中全部參數
-h,–help
輸出幫助信息
@
排除不需要監視的文件,可以是相對路徑,也可以是絕對路徑。
–fromfile
從文件讀取需要監視的文件或排除的文件,一個文件一行,排除的文件以@開頭。
-m, –monitor
接收到一個事情而不退出,無限期地執行。默認的行爲是接收到一個事情後立即退出。
-d, –daemon
跟–monitor一樣,除了是在後臺運行,需要指定–outfile把事情輸出到一個文件。也意味着使用了–syslog。
-o, –outfile
輸出事情到一個文件而不是標準輸出。
-s, –syslog
輸出錯誤信息到系統日誌
-r, –recursive
監視一個目錄下的所有子目錄。
-q, –quiet
指定一次,不會輸出詳細信息,指定二次,除了致命錯誤,不會輸出任何信息。
–exclude
正則匹配需要排除的文件,大小寫敏感。
–excludei
正則匹配需要排除的文件,忽略大小寫。
-t , –timeout
設置超時時間,如果爲0,則無限期地執行下去。
-e , –event
指定監視的事件。
-c, –csv
輸出csv格式。
–timefmt
指定時間格式,用於–format選項中的%T格式。
–format
指定輸出格式。
%w 表示發生事件的目錄
%f 表示發生事件的文件
%e 表示發生的事件
%Xe 事件以“X”分隔
%T 使用由–timefmt定義的時間格式
3.2 可監聽事件
access 訪問,讀取文件。
modify 修改,文件內容被修改。
attrib 屬性,文件元數據被修改。
move 移動,對文件進行移動操作。
create 創建,生成新文件
open 打開,對文件進行打開操作。
close 關閉,對文件進行關閉操作。
delete 刪除,文件被刪除。
3.3 使用示例
以監聽vue項目,發現有文件變化後,執行 npm run build
命令構建代碼爲例
假設vue項目文件目錄爲: /production/sites/vue-program
根據vue項目基本目錄結構,則我們需要監聽該目錄下的src目錄,且只監聽文件變化的事件
inotifywait /production/sites/vue-program/src #只監聽src目錄,因爲package.json等文件在構建完成後也會被修改
-r #監聽所有子目錄文件
--timefmt '%d/%m/%y %H:%M' #時間輸出格式,如果--format設置了%f,則必須指明
--format "%T %f" #輸出格式
-e MODIFY #只監聽文件修改事件
--exclude '^.*.swp$' #如果直接使用vim等編輯工具改動文件,會觸發 .swp 臨時文件的修改事件,所以我們需要排除所有正則形如 /^\.((?!\.swp$).)*$/ 的文件,但此表達式在linux中貌似不行,所以用的.*.swp
以上爲了方便閱讀,對每個參數換行並加了註釋,整理爲一行如下:
inotifywait /production/sites/vue-program/src -r --timefmt '%d/%m/%y %H:%M' --format "%T %f" -e MODIFY --exclude '^.*.swp$'
運行可以觀察是我們想要的效果,那我們監聽到事件後加入構建代碼到指令,創建shell文件 auto_build.sh
#!/bin/bash
projectDir=/production/sites/vue-program;
while inotifywait $projectDir/src -r --timefmt '%d/%m/%y %H:%M' --format "%T %f" -e MODIFY --exclude '^.*.swp$'
do
cd $projectDir && git pull && npm run build
done
此處由於 -m
參數會監聽多個文件,所以git一次提交可能會觸發多個修改事件,因此沒有使用 -m
,而是通過while
去觸發inotifywait監聽,然後等待在這裏;而事件觸發後再執行一遍 git pull
是因爲第一個文件修改事件觸發後,git未必將所有文件替換完,爲保證npm run build
指令執行時代碼全部更新,所以在此處又主動執行了一遍 git pull
之後就可以啓動腳本了
nohup /bin/bash auto_build.sh >> /tmp/auto_build.log 2>&1
這樣,配合crontab定時拉取代碼,當前端代碼文件變化後,就會自動構建了,省去了每次手動操作的繁瑣和遺漏。
更多信息可參閱官方文檔