1、簡介shell
Inotify 是一個 Linux 內核特性,它監控文件系統,而且及時向專門的應用程序發出相關的事件警告,好比刪除、讀、寫和卸載操做等。您還能夠跟蹤活動的源頭和目標等細節。在實際項目中,若是項目帶有配置文件,那麼怎麼讓配置文件的改變和項目程序同步而不須要重啓程序呢?一個明顯的應用是:在一個程序中,使用Inotify監視它的配置文件,若是該配置文件發生了更改(更新,修改)時,Inotify會產生修改的事件給程序,應用程序就能夠實現從新加載配置文件,檢測哪些參數發生了變化,並在應用程序內存的一些變量作相應的修改。固然另外一種方法能夠是經過cgi註冊命令,並經過命令更新內存數據及更新配置文件
cookie
Inotify 能夠監視的文件系統事件包括:
IN_ACCESS,即文件被訪問
IN_MODIFY,文件被 write
IN_ATTRIB,文件屬性被修改,如 chmod、chown、touch 等
IN_CLOSE_WRITE,可寫文件被 close
IN_CLOSE_NOWRITE,不可寫文件被 close
IN_OPEN,文件被 open
IN_MOVED_FROM,文件被移走,如 mv
IN_MOVED_TO,文件被移來,如 mv、cp
IN_CREATE,建立新文件
IN_DELETE,文件被刪除,如 rm
IN_DELETE_SELF,自刪除,即一個可執行文件在執行時刪除本身
IN_MOVE_SELF,自移動,即一個可執行文件在執行時移動本身
IN_UNMOUNT,宿主文件系統被 umount
IN_CLOSE,文件被關閉,等同於(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
IN_MOVE,文件被移動,等同於(IN_MOVED_FROM | IN_MOVED_TO)
注:上面所說的文件也包括目錄。
測試
2、使用Inofityflex
要使用 inotify,您必須具有一臺帶有 2.6.13 或更新內核的 Linux 機器(之前的 Linux 內核版本使用更低級的文件監控器dnotify)。若是您不知道內核的版本,請轉到 shell,輸入 uname -a
:ui
您還能夠檢查機器的 /usr/include/sys/inotify.h 文件。若是它存在,代表您的內核支持 inotify。spa
使用 inotify 很簡單:建立一個文件描述符,附加一個或多個監視器(一個監視器 是一個路徑和一組事件),而後使用 read()
方法從描述符獲取事件信息。read()
並不會用光整個週期,它在事件發生以前是被阻塞的。.net
更好的是,由於 inotify 經過傳統的文件描述符工做,您能夠利用傳統的 select()
系統調用來被動地監控監視器和許多其餘輸入源。兩種方法 — 阻塞文件描述符和使用 select()
— 都避免了繁忙輪詢。code
Inotify 提供 3 個系統調用,它們能夠構建各類各樣的文件系統監控器:blog
int fd = inotify_init()
在內核中建立 inotify 子系統的一個實例,成功的話將返回一個文件描述符,失敗則返回 -1。就像其餘系統調用同樣,若是 inotify_init()
失敗,請檢查 errno
以得到診斷信息。inotify_add_watch(fd,path,mask)
用於添加監視器。每一個監視器必須提供一個路徑名和相關事件的列表(每一個事件由一個常量指定,好比 IN_MODIFY)。要監控多個事件,只需在事件之間使用邏輯操做符或 — C 語言中的管道線(|
)操做符。若是 inotify_add_watch()
成功,該調用會爲已註冊的監視器返回一個唯一的標識符;不然,返回 -1。使用這個標識符更改或刪除相關的監視器。int ret = inotify_rm_watch(fd, wd)
刪除一個監視器。 此外,還須要 read()
和 close()
系統調用。若是描述符由 inotify_init()
生成,則調用 read()
等待警告。假設有一個典型的文件描述符,應用程序將阻塞對事件的接收,這些事件在流中表現爲數據。文件描述符上的由 inotify_init()
生成的通用close()
刪除全部活動監視器,並釋放與 inotify 實例相關聯的全部內存(這裏也用到典型的引用計數警告。與實例相關聯的全部文件描述符必須在監視器和 inotify 消耗的內存被釋放以前關閉)。事件
3、測試Inotify
在文件 /usr/include/sys/inotify.h. 中,您能夠找到事件結構的定義,它是一種 C 結構,以下所示:
結構中的char name是不佔空間的,至關於char name[0],因此sizeof(struct inotify_event)長度是16,實際上該結構數據的總長度應該是16+len,數據是緊跟在uinit32_t len後面的數據。
測試代碼以下:
以上代碼須要注意的地方:
1.若是在/tmp目錄下touch kill文件,程序則會退出
2.若是隻有一個add watch 一個file,那麼這個file的更改產生的event事件中event->len是爲0,須要額外的處理,此代碼省略了具體的處理過程,以註釋代替
3.若是監測的是文件或目錄的更改,使用 echo "xxx" >> file,會產生一個event事件,而使用echo "xxx" > file 會產生兩個event事件,查了相關的資料,多是由於後者須要先清空file文件內容,形成第一次event事件,再將xxx寫入file保存,形成了第二次的event事件。