ファイル操作を検知するincron
incronを利用してファイルの作成、編集、削除を検知します。 お客さんからメールファイルの作成を検知してDBに登録して欲しいという依頼から始まったものです。
[ 目次 ]
はじめに
こんにちは、香港に住んでいるWEBデベロッパーのなかむ(@nakanakamu0828)です。
今回はCentOS7で運用しているサーバーに、incronをインストールして試して行きたいと思います。きっかけはお客さんから「メールを受信した際にメールデータをDBに取り込んで欲しい」という依頼を受けたためです。「なぜメール受信をトリガーにしてスクリプトを起動しないの?」と思う方もいらっしゃると思います。今回は以下の2点の理由からメールファイルを読み込むという仕様にしました。
- 既にメールサーバーが運用中で社員が利用しています。なのでpostfixの変更はなるべく避けたかった
- 受信したメールをトリガーとしてスクリプトを実行する場合、標準入力としてデータを受取るためリカバリできない。リカバリするときはメールファイルを読み込むことになるので、最初からファイルを読み込む作りにしたほうがいい
"incron"とは
- ファイルの作成、変更、削除、移動といったイベントを検知して、登録したジョブを実行させる
- Linuxのinotifyという仕組み
- crontabと似ていて
incrontab
というコマンドで操作する
"incron"のインストール
インストール
$ sudo yum --enablerepo=epel install incron
起動
$ sudo systemctl start incrond
停止
$ sudo systemctl stop incrond
incrontabコマンドについて
# ジョブの設定が書かれたファイルで設定
incrontab ファイル名
# ジョブの設定の一覧を表示
incrontab -l
# ジョブの設定をviなどで編集
incrontab -e
# ジョブの設定を削除
incrontab -r
# ジョブの反映
incrontab -d
簡単なphpでincronを実行
phpファイル作成
HOMEディレクトリにtmp
ディレクトリを作成しphpファイルを用意していきます。
phpファイルの中身は引数をログファイルに出力する簡単なものです。
$ cd ~
$ mkdir -p tmp/target && cd tmp
$ cat <<EOF > args.php
<?php
file_put_contents("[Homeディレクトリパス]/tmp/" . date('Ymd') . '.log', join(",", $argv), FILE_APPEND|LOCK_EX);
EOF
※ ~/tmp/target
は検知用のディレクトリとして利用します。
incrontabに設定
作成、変更、削除のイベントを受けとる設定をします。
ファイルを検知する対象ディレクトリは、[HOMEディレクトリ]/tmp/target
です。
$ incrontab -e
以下を設定する
[HOMEディレクトリ]/tmp/target IN_CREATE,IN_MODIFY,IN_DELETE /usr/bin/php [HOMEディレクトリ]/tmp/args.php $@ $# $% $&
$ incrontab -d
設定を反映
検知可能なイベント
- IN_ACCESS
File was accessed (read) - IN_ATTRIB
Metadata changed (permissions, timestamps, extended attributes, etc.) - IN_CLOSE_WRITE
File opened for writing was closed - IN_CLOSE_NOWRITE
File not opened for writing was closed - IN_CREATE
File/directory created in watched directory - IN_DELETE
File/directory deleted from watched directory - IN_DELETE_SELF
Watched file/directory was itself deleted - IN_MODIFY
File was modified - IN_MOVE_SELF
Watched file/directory was itself moved - IN_MOVED_FROM
File moved out of watched directory - IN_MOVED_TO
File moved into watched directory - IN_OPEN
File was opened
以下のコマンドを実行することでイベントの一覧も取得可能
$ incrontab -t | sed -e 's/,/\n/g'
IN_ACCESS
IN_MODIFY
IN_ATTRIB
IN_CLOSE_WRITE
IN_CLOSE_NOWRITE
IN_OPEN
IN_MOVED_FROM
IN_MOVED_TO
IN_CREATE
IN_DELETE
IN_DELETE_SELF
IN_CLOSE
IN_MOVE
IN_ONESHOT
IN_ALL_EVENTS
IN_DONT_FOLLOW
IN_ONLYDIR
IN_MOVE_SELF
コマンドで利用するワイルドカードについて
-
$@
監視しているパス -
$#
イベントが発生したファイルまたはディレクトリの監視しているパスからの相対パスです
監視しているパス自体でイベントが起きたら空文字です -
$%
どのイベントが起きたか -
$&
どのイベントが起きたかです(数字) -
$$
$ から始まると特殊な扱いになるので $$ で $ を表します
incrontabの動作確認
crontabと同様で /var/log/cron
にログが出力されます。
tailコマンドを使ってログを監視しましょう
$ sudo tail -100f /var/log/cron
ターミナルの別タブ or 別ウィンドウを開いて、ファイルを作成、更新、削除してみます。
$ cd ~/tmp
$ touch target/1.txt
$ echo 'test' >> target/1.txt
$ rm -f target/1.txt
ログは以下のようになります。
Aug 31 19:55:57 [hostname] incrond[23871]: ([username]) CMD (/usr/bin/php [Homeディレクトリ]/tmp/args.php [Homeディレクトリ]/tmp/target 1.txt IN_CREATE 256)
Aug 31 19:56:40 [hostname] incrond[23871]: ([username]) CMD (/usr/bin/php [Homeディレクトリ]/tmp/args.php [Homeディレクトリ]/tmp/target 1.txt IN_MODIFY 2)
Aug 31 19:57:04 [hostname] incrond[23871]: ([username]) CMD (/usr/bin/php [Homeディレクトリ]/tmp/args.php [Homeディレクトリ]/tmp/target 1.txt IN_DELETE 512)
最後に
今回はincronを試しました。業務上はメールディレクトリをincronで検知して、メールファイルを読み込み、DBに登録しています。
あまり利用する機会がないとは思いますが、経験の積み重ねが役立つエンジニアの世界です。
多少脱線してでも学びを得て、柔軟な対応ができるエンジニアを目指していきたいですね!!