hana_shinのLinux技術ブログ

Linuxの技術情報を掲載しています。特にネットワークをメインに掲載していきます。

inotifywaitコマンドの使い方

1 inotifywaitコマンドとは?

ファイルやディレクトの作成/削除等で発生するイベントを監視するコマンドです。以下のシステムコールを使ってイベントを監視しています。
・inotify_init
・inotify_add_watch

2 検証環境

CentOS版数は以下のとおりです。

[root@server ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

カーネル版数は以下のとおりです。

[root@server ~]# uname -r
3.10.0-1160.el7.x86_64

3 inotifywaitコマンドのインストール方法

inotify-toolsパッケージはepelレポジトリにあるので、まずepel-releaseパッケージをインストールします。

[root@server ~]# yum -y install epel-release

次に、notify-toolsパッケージをインストールします。

[root@server ~]# yum -y install inotify-tools

inotifywaitコマンドの版数を確認します。

[root@server ~]# inotifywait --help
inotifywait 3.14
-snip-

4 オプション一覧

オプションは以下のとおりです。

[root@server ~]# inotifywait --help
inotifywait 3.14
Wait for a particular event on a file or set of files.
Usage: inotifywait [ options ] file1 [ file2 ] [ file3 ] [ ... ]
Options:
        -h|--help       Show this help text.
        @<file>         Exclude the specified file from being watched.
        --exclude <pattern>
                        Exclude all events on files matching the
                        extended regular expression <pattern>.
        --excludei <pattern>
                        Like --exclude but case insensitive.
        -m|--monitor    Keep listening for events forever.  Without
                        this option, inotifywait will exit after one
                        event is received.
        -d|--daemon     Same as --monitor, except run in the background
                        logging events to a file specified by --outfile.
                        Implies --syslog.
        -r|--recursive  Watch directories recursively.
        --fromfile <file>
                        Read files to watch from <file> or `-' for stdin.
        -o|--outfile <file>
                        Print events to <file> rather than stdout.
        -s|--syslog     Send errors to syslog rather than stderr.
        -q|--quiet      Print less (only print events).
        -qq             Print nothing (not even events).
        --format <fmt>  Print using a specified printf-like format
                        string; read the man page for more details.
        --timefmt <fmt> strftime-compatible format string for use with
                        %T in --format string.
        -c|--csv        Print events in CSV format.
        -t|--timeout <seconds>
                        When listening for a single event, time out after
                        waiting for an event for <seconds> seconds.
                        If <seconds> is 0, inotifywait will never time out.
        -e|--event <event1> [ -e|--event <event2> ... ]
                Listen for specific event(s).  If omitted, all events are
                listened for.

Exit status:
        0  -  An event you asked to watch for was received.
        1  -  An event you did not ask to watch for was received
              (usually delete_self or unmount), or some error occurred.
        2  -  The --timeout option was given and no events occurred
              in the specified interval of time.

Events:
        access          file or directory contents were read
        modify          file or directory contents were written
        attrib          file or directory attributes changed
        close_write     file or directory closed, after being opened in
                        writeable mode
        close_nowrite   file or directory closed, after being opened in
                        read-only mode
        close           file or directory closed, regardless of read/write mode
        open            file or directory opened
        moved_to        file or directory moved to watched directory
        moved_from      file or directory moved from watched directory
        move            file or directory moved to or from watched directory
        create          file or directory created within watched directory
        delete          file or directory deleted within watched directory
        delete_self     file or directory was deleted
        unmount         file system containing file or directory unmounted

4 指定したイベントを監視する方法(-e)

4.1 イベントの種類

イベントには以下のものがあります。

Events:
        access          file or directory contents were read
        modify          file or directory contents were written
        attrib          file or directory attributes changed
        close_write     file or directory closed, after being opened in
                        writeable mode
        close_nowrite   file or directory closed, after being opened in
                        read-only mode
        close           file or directory closed, regardless of read/write mode
        open            file or directory opened
        moved_to        file or directory moved to watched directory
        moved_from      file or directory moved from watched directory
        move            file or directory moved to or from watched directory
        create          file or directory created within watched directory
        delete          file or directory deleted within watched directory
        delete_self     file or directory was deleted
        unmount         file system containing file or directory unmounted

4.2 openイベントの使い方(-e open)

openイベントは、ファイルやディレクトリをオープンしたときに発生します。

まず、テスト用のディレクトリを作成します。

[root@server ~]# mkdir /test

ファイルを作成します。

[root@server ~]# touch /test/test.txt

inotifywaitコマンドを実行します。このとき、ファイル(test.txt)をopenしたときのイベントを監視します。

[root@server ~]# inotifywait -e open /test/test.txt
Setting up watches.
Watches established.

もう1つターミナルを開きます。そして、catコマンドでファイルをリードします。

[root@server ~]# cat /test/test.txt
[root@server ~]#

inotifywaitコマンドの実行結果を確認します。OPENイベントが発生していることがわかります。

[root@server ~]# inotifywait -e open /test/test.txt
Setting up watches.
Watches established.
/test/test.txt OPEN

lsコマンドでディレクトリの中身を表示しても、OPENイベントが発生します。lsコマンドで/tmpの中身を表示してみます。

[root@server ~]# inotifywait -e open /test
Setting up watches.
Watches established.

/tmpディレクトリに対して、lsコマンドを実行します。

[root@server ~]# ls /test/
test.txt

inotifywaitコマンドの実行結果を確認します。OPENイベントが発生していることがわかります。

[root@server ~]# inotifywait -e open /test
Setting up watches.
Watches established.
/test/ OPEN,ISDIR

4.3 attribイベントの使い方(-e attrib)

attribイベントは、ファイルやディレクトリの属性が変更されたときに発生します。

[root@server ~]# inotifywait -e attrib /test/test.txt
Setting up watches.
Watches established.

ファイルの属性を確認します。

[root@server ~]# ls -l /test/test.txt
-rw-r--r--. 1 root root 0  4月 25 19:09 /test/test.txt

ファイルの属性を変更します。

[root@server ~]# chmod 666 /test/test.txt

inotifywaitコマンドの実行結果を確認します。ATTRIBイベントが発生していることがわかります。

[root@server ~]# inotifywait -e attrib /test/test.txt
Setting up watches.
Watches established.
/test/test.txt ATTRIB

4.4 modifyイベントの使い方(-e modify)

MODIFYイベントは、ファイルを作成したりファイルに書き込みをすると発生します。
ここでは、/testディレクトリ配下にファイルが作成されたら発生するMODIFYイベントを監視してみます。

[root@server ~]# inotifywait -e modify /test
Setting up watches.
Watches established.

ファイルに書き込みをします。

[root@server ~]# echo 11 > /test/aa

inotifywaitコマンドの実行結果を確認します。MODIFYイベントが発生していることがわかります。

[root@server ~]# inotifywait -e modify /test
Setting up watches.
Watches established.
/test/ MODIFY aa

4.5 deleteイベントの使い方(-e delete)

DELETEイベントは、指定したディレクト配下のファイルやディレクトリが削除されると発生します。

[root@server ~]# inotifywait -e delete /test
Setting up watches.
Watches established.

テスト用のファイルを作成します。

[root@server ~]# touch /test/test.txt

テスト用のファイルを削除します。

[root@server ~]# rm /test/test.txt
rm: 通常の空ファイル `/test/test.txt' を削除しますか? y

inotifywaitコマンドの実行結果を確認します。DELETEイベントが発生していることがわかります。

[root@server ~]# inotifywait -e delete /test
Setting up watches.
Watches established.
/test/ DELETE test.txt

4.6 delete_selfイベントの使い方(-e delete_self)

DELETE_SELFイベントは、指定したファイルやディレクトリが削除されると発生します。

テスト用のファイルを作成します。

[root@server ~]# touch /test/test.txt

ファイルが削除されたら発生するDELETE_SELFイベントを監視してみます。

[root@server ~]# inotifywait -m -e delete_self /test/test.txt
Setting up watches.
Watches established.

ファイルを削除します。

[root@server ~]# rm /test/test.txt
rm: 通常の空ファイル `/test/test.txt' を削除しますか? y

inotifywaitコマンドの実行結果を確認します。DELETE_SELFイベントが発生していることがわかります。

[root@server ~]# inotifywait -m -e delete_self /test/test.txt
Setting up watches.
Watches established.
/test/test.txt DELETE_SELF

4.7 createイベントの使い方(-e create)

CREATEイベントは、指定したディレクトリ配下にファイルやディレクトリを作成すると発生します。

テスト用のディレクトリを作成します。

[root@server ~]# mkdir /a

ディレクトリを作成したら発生するCREATEイベントを監視してみます。

[root@server ~]# inotifywait -m -e create /a
Setting up watches.
Watches established.

/aディレクトリに/bディレクトリを作成します。

[root@server ~]# mkdir /a/b

inotifywaitコマンドの実行結果を確認します。CREATEイベントが発生していることがわかります。

[root@server ~]# inotifywait -m -e create /a
Setting up watches.
Watches established.
/a/ CREATE,ISDIR b

4.8 moved_fromイベントの使い方(-e moved_from)

MOVED_FROMイベントは、指定したディレクトリ配下からファイルやディレクトを移動すると発生します。

テスト用のファイルを作成します。

[root@server ~]# touch /test/test.txt

/testディレクトリ配下にファイルが移動されたら発生するMOVED_FROMイベントを監視してみます。

[root@server ~]# inotifywait -m -e moved_from /test
Setting up watches.
Watches established.

ファイルを/testディレクトリから/tmpディレクトリに移動します。

[root@server ~]# mv /test/test.txt /tmp/

inotifywaitコマンドの実行結果を確認します。MOVED_FROMイベントが発生していることがわかります。

[root@server ~]# inotifywait -m -e moved_from /test
Setting up watches.
Watches established.
/test/ MOVED_FROM test.txt

4.9 moved_toイベントの使い方(-e moved_to)

moved_toイベントは、指定したディレクトリ配下へファイルやディレクトを移動すると発生します。

テスト用のファイルを作成します。

[root@server ~]# touch /test/test.txt

/tmpディレクトリ配下にファイルが移動されたら発生するMOVED_TOイベントを監視してみます。

[root@server ~]# inotifywait -m -e moved_to /tmp
Setting up watches.
Watches established.

ファイルを/testディレクトリから/tmpディレクトリに移動します。

[root@server ~]# mv /test/test.txt /tmp/

inotifywaitコマンドの実行結果を確認します。MOVED_TOイベントが発生していることがわかります。

[root@server ~]# inotifywait -m -e moved_to /tmp
Setting up watches.
Watches established.
/tmp/ MOVED_TO test.txt

4.10 unmountイベントの使い方(-e )

unmountイベントは、ファイルやディレクトリを含んだファイルシステムをアンマウントすると発生します。

まず、ループバックデバイスとして使うファイルを作成します。なお、ファイルの作成方法は、ファイルの作り方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# fallocate -l 100M disk.img

ループバックデバイスを作成します。ループバックデバイスの使い方は、losetupコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。

[root@server ~]# losetup -f /root/disk.img

ループバックデバイスを確認します。

[root@server ~]# losetup -l
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE
/dev/loop0         0      0         0  0 /root/disk.img

ループバックデバイスファイルシステムを作成します。

[root@server ~]# mkfs.ext4 /dev/loop0 

作成したファイルシステムを/mntにマウントします。

[root@server ~]# mount -t ext4 /dev/loop0 /mnt

ファイルシステムを確認します。ファイルシステムが/mntにマウントされたことがわかります。

[root@server ~]# df -ht ext4
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/loop0        93M  1.6M   85M    2% /mnt

ファイルを作成します。

[root@server ~]# touch test.txt /mnt

ファイルシステムをアンマウントしたら発生するUNMOUNTイベントを監視してみます。

[root@server ~]# inotifywait -e unmount /mnt
Setting up watches.
Watches established.

作成したフィルシステムをアンマウントします。

[root@server ~]# umount /mnt

inotifywaitコマンドの実行結果を確認します。UNMOUNTイベントが発生していることがわかります。

[root@server ~]# inotifywait -e unmount /mnt
Setting up watches.
Watches established.
/mnt/ UNMOUNT

5 リカーシブオプションの使い方(-r)

-rはディレクトリ配下の全てのファイル、ディレクトリを監視対象にするオプションです。

5.1 事前準備

テスト用のディレクトリを作成します。

[root@server ~]# mkdir -p /a/b/c

テスト用のファイルを作成します。

[root@server ~]# touch /a/b/c/test.txt

作成したファイルを確認します。

[root@server ~]# ls -l /a/b/c/test.txt
-rw-r--r--. 1 root root 0  5月 14 09:48 /a/b/c/test.txt

5.2 リカーシブオプションを指定しない場合

[root@server ~]# inotifywait -m /a
Setting up watches.
Watches established.

ファイルに書き込みをします。

[root@server ~]# echo 11 > /a/b/c/test.txt

ファイルに書き込みをしてもイベントが発生しないことがわかります(期待値)。

[root@server ~]# inotifywait -m /a
Setting up watches.
Watches established.

5.3 リカーシブオプションを指定した場合

[root@server ~]# inotifywait -m -r /a
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.

ファイルに書き込みをします。

[root@server ~]# echo 11 > /a/b/c/test.txt

MODIFY,OPEN,CLOSE_WRITE,CLOSEのイベントが表示されていることがわかります(期待値)。

[root@server ~]# inotifywait -m -r /a
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
/a/b/c/ MODIFY test.txt
/a/b/c/ OPEN test.txt
/a/b/c/ MODIFY test.txt
/a/b/c/ CLOSE_WRITE,CLOSE test.txt

6 時刻を表示する方法(timefmt)

timefmtは、時刻の表示形式を指定するオプションです。timefmtは、formatオプションと一緒に使う必要があります。formatは、表示項目を指定します。表示項目としては、時刻(%T)、監視対象(%w)、監視イベント(%e)等が指定できます。

[root@server ~]# inotifywait -m --format '%T %w %f %e' --timefmt '%F %T' /a
Setting up watches.
Watches established.

/aディレクトリ配下のファイルを表示します。

[root@server ~]# ls /a

1列目に時刻が表示されていることがわかります。

[root@server ~]# inotifywait -m --format '%T %w %f %e' --timefmt '%F %T' /a
Setting up watches.
Watches established.
2022-05-14 18:14:44 /a/  OPEN,ISDIR
2022-05-14 18:14:44 /a/  CLOSE_NOWRITE,CLOSE,ISDIR

7 出力メッセージをファイルに保存する方法(o)

-cは、inotifywait が出力するメッセージをファイルに保存するオプションです。

[root@server ~]# inotifywait -m /a -o event.log
Setting up watches.
Watches established.

/aディレクトリ配下のファイルを表示します。

[root@server ~]# ls /a

フメッセージを保存したファイルを確認します。

[root@server ~]# cat event.log
/a/ OPEN,ISDIR
/a/ CLOSE_NOWRITE,CLOSE,ISDIR

8 デーモンプロセスとして起動する方法(-d)

-dはinotifywaitプロセスをデーモンプロセスとして動かすオプションです。このとき、-oオプションも一緒に指定する必要があります。-oオプションで、デーモンプロセスが出力するメッセージの出力先を指定します。

まず、inotifywaitコマンドを実行して、inotifywaitをデーモンプロセスとして起動します。

[root@server ~]# inotifywait -m -d -o /tmp/event.log /a

psコマンドを実行して、プロセスの状態を確認します。TTY列が?となっているので、デーモンプロセスであることがわかります。なお、デーモンプロセスとは、標準入出力を持たないプロセスのことです。

[root@server ~]# ps -C inotifywait -o comm,pid,ppid,tty
COMMAND            PID   PPID TT
inotifywait       2131      1 ?

inotifywaitプロセスを終了します。

[root@server ~]# kill -9 2131
[root@server ~]#

9 csvフォーマットで出力する方法(-c)

-cはinotifywaitが出力するメッセージを","で区切るオプションです。

[root@server ~]# inotifywait -m -c /a
Setting up watches.
Watches established.

/aディレクトリ配下のファイルを表示します。

[root@server ~]# ls /a

各列が","で区切られていることがわかります。

[root@server ~]# inotifywait -m -c /a
Setting up watches.
Watches established.
/a/,"OPEN,ISDIR",
/a/,"CLOSE_NOWRITE,CLOSE,ISDIR",

Z 参考情報

私が業務や記事執筆で参考にした書籍を以下のページに記載します。
Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ