[Linux]ホットフォルダ/ファイル検出して処理をしたい
2015/01/21
ホットフォルダ本来はどうすべきか
ファイルの検出を同期で行うのが正しいです。ファイルの作成や削除はフォルダの更新を検出すればいいのです。
本来はファイルを検出したらそのファイルが他のプログラムがopenしていないことを確認することでファイルが書き終わっている(成功してても失敗でも)と認識すべきです。それで壊れていたのならエラー処理(エラーフォルダに移動するのが鉄板)して次のファイルを処理させます。
とはいっても専用のプログラムをシステムコール使って実装しないとできないので簡単にはいきませんね。
Linuxならinotify-toolsがある
inotify-toolsはファイルサーバの同期などで使うツールですが、ファイル操作検出してくれるツールで今回はinotifywaitというコマンドを使えばあんがいすっきり実装できます。
inotify-toolsインストール
下記のようにして inotify-tools を導入すると inotifywaitが使えるようになります。インストールはrootで行います。
# yum --enablerepo=epel -y install inotify-tools
ファイル検出の方法
下記のコマンドラインで書き込み処理のCLOSEと、ファイルが移動してきたことを検知できます。
# inotifywait -e CLOSE_WRITE,MOVED_TO /tmp/hotfolder Setting up watches. Watches established.
この状態でこの/tmp/hotfolderにファイルをコピーしてxxx.xmlで保存すると。
/tmp/hotfolder/ CLOSE_WRITE,CLOSE xxx.xml
移動の場合は
/tmp/hotfolder/ MOVED_TO yyy.xml
検出するイベントの指定で -e CLOSE_WRITE,MOVED_TO としていて CREATE とMODIFYは指定しません(これ重要)。ネットでこのコマンドの使い方みると多くはCREATE とMODIFYを使う例が多くみられますがこればNGです。CREATEはファイル名が登録された状態でファイルの中身は書き込み中の場合があります、MODIFYは書き込み中でまだ書いている途中の可能性があります。なのでファイルが完成しているCLOSE_WRITEとMOVED_TOで判断する必要があるのです。
inotifywaitを使って実装してみる
#!/bin/bash cd /tmp/hotfolder while [ 1 ] do HITFILE=`ls -1rt *.xml 2>; /dev/null | head -n 1` if [ -z "${HITFILE}" ] then /usr/bin/inotifywait -qq -s -e CLOSE_WRITE,MOVED_TO /tmp/hotfolder -t 10 else # ファイル検出時の処理 # 例として行数を表示して削除している wc -l ${HITFILE} rm ${HITFILE} # fi done
最初のスクリプトのsleepの部分を置き換えてinotifywaitを使ってみました。/tmp/hotfolderにファイルの書き込みが終わるか、ファイルが移動やリネームされるのが終わるまで待ちますので。10秒のタイムラグはなくなります。-tで10を指定しているのはおまじないです。ずーっとまってしまうのが怖かったのでいったん10秒で抜けてファイルがあるかみています。 また最初にファイルの存在チェックしているのは、すでに格納されたファイルがあった場合に処理してから待たせるためです。しかし、このせいで起動直後、書き込み中のファイルを検出してしまうリスクはあります。
もう少しここは気を利かせる方法をまた考えます。
inotifywaitの使い方
コマンドのヘルプを一応コピーしておきます。
#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. @ Exclude the specified file from being watched. --exclude Exclude all events on files matching the extended regular expression . --excludei 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 Read files to watch from or `-' for stdin. -o|--outfile Print events to 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 Print using a specified printf-like format string; read the man page for more details. --timefmt strftime-compatible format string for use with %T in --format string. -c|--csv Print events in CSV format. -t|--timeout When listening for a single event, time out after waiting for an event for seconds. If is 0, inotifywait will never time out. -e|--event [ -e|--event ... ] 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
関連記事
-
正規表現編集とテストを簡単に行える正規表現チェックツール
正規表現の編集やテストをさくさくやりたい その場にLinuxの環境でもあればse …
-
[AjaXplorer]レンタルサーバのファイル管理
レンタルサーバのファイル管理するエクスプローラがほしい サーバにはレンタルサーバ …