世界を旅して暮らしたい放浪エンジニアブログ

ファイル操作を検知する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に登録しています。
あまり利用する機会がないとは思いますが、経験の積み重ねが役立つエンジニアの世界です。
多少脱線してでも学びを得て、柔軟な対応ができるエンジニアを目指していきたいですね!!

参考記事

前のページ

次のページ

Profile

なかむ🇭🇰Webデベロッパー

なかむ🇭🇰Webデベロッパー

香港在住4年目になるWEBエンジニアのなかむです。 現在は、LaravelやRailsを利用したWEB開発を中心にエンジニアをしています。 顧客は全て日本の企業になります。リモート開発にて各企業様の支援を行なっております

プロフィール詳細はこちら

Latest Posts