inotifywait的安裝及基本使用

由於每次前端同學的vue項目push到git後,都需要私下告訴我,然後我更新代碼並重新構建,嫌麻煩,但由於本地環境的ip非公網ip,webhook不可達,所以只能使用crontab定時拉取代碼,再配合inotifywait監聽文件變化,自動build構建代碼,遂寫此文記錄下inotifywait的安裝和基本使用,以便後續查閱。

一、inotifywait介紹

Inotify 一種強大的、細粒度的、異步文件系統監控機制,它滿足各種各樣的文件監控需要,可以監控文件系統的訪問屬性、讀寫屬性、權限屬性、刪除創建、移動等操作,也就是可以監控文件發生的一切變化。

inotify-tools 是一個C庫和一組命令行的工作,提供Linux下inotify的簡單接口。inotify-tools安裝後會得到inotifywaitinotifywatch這兩條命令:

  • 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定時拉取代碼,當前端代碼文件變化後,就會自動構建了,省去了每次手動操作的繁瑣和遺漏。

更多信息可參閱官方文檔

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章