星期六, 3月 13, 2010

inotify - 讓 kernel 幫你監控檔案

自從 Linux Kernel 2.6.13,linux 就提供了 inotify 的 API 讓使用者以 event 的方式監控檔案。這顯然比傳統 busy checking 的方式有效率多了,除了用的是 kernel space 的 memory 以外幾乎沒有理由不用這麼好用的機制了吧!
inotify 提供監控的事件可以在 manual 裡找到 (man inotify) 在這邊就不贅述。使用上其實也很簡單,首先呼叫 inotify_init() 取得一個 file descriptor,將來只要讀這個 fd (block/non-block) 就可以取得 event,可以視為一個 event queue,然後把想要監控的檔案、訊息透過 inotify_add_watch 就可以加入監控的列表。接下來只要讀取剛剛取得的 fd 就可以了。需要注意的地方是,如果監控的目標是 directory,那 read 用的 buffer 以及 size 必須包含檔案名稱的大小然後一起 read,不然會有 EINVAL 的錯誤。

以前就聽過看過這東西,這次會翻出來是因為我正在用 latex 寫一篇文章但每次都要 compile/make 實在很麻煩(雖然說 vim 可以設 key binding 來直接 make 可是還是懶了點)於是就寫了一個等某個 inotify event 的小程式,有一個叫做 inotify-tools 的工具包裡面有 inotifywait 但是他只能針對某個存在的 file 進行監控,而 vim 在寫檔時會移動/刪除原本的檔案,造成監控中斷,所以我只好另外寫了這個 tool 對於目前的 WD 內特定的 filename 的某些特定 event 做等待。也就是說我監控的對象是這個 directory 但是我只 care 某個特定檔案發生的某些 event。

以下是我寫的 iwatch, 以 MIT License 釋出。
http://moon.cse.yzu.edu.tw/~s961449/iwatch.c


應用在我上面提到的自動編譯 latex, 可以用這個  bash script:
#!/bin/bash
id=0
while iwatch -e modify proposal.tex
do
kill -KILL $id
make
acroread proposal.pdf &
id=$!
done
執行這個 script 會監控目標 .tex 發現更變以後自動重新 make, 然後打開 pdf viewer,這邊是用 acroread,也可以用 foxit (比較快)。

沒有留言: