[2016/07/29 追記]
systemd.pathを使えば同じことができそうなことが判明・・・orz
[2016/07/29 さらに追記]
systemd.pathからUnitにファイルパスを渡す方法が不明。できないのかな。
できないのならこのスクリプトも意味があるけど。
どなたかご存知でしたら教えてください。
事前準備
inotify-toolsをインストール (Redhat系)
yum install -y inotify-tools
ソース
watch-file.sh
#!/bin/bash -eu
trap "exit 0" 3 # QUITシグナルで停止
WATCH_DIR=$1 # 監視するディレクトリ
FILE_PATTERN=$2 # ファイル名正規表現
COMMAND=$3 # ファイル更新時に実行するコマンド
# --formatで"ディレクトリ ファイル名 イベント"の形式で出力するように指定
inotifywait -e CLOSE_WRITE -m -r ${WATCH_DIR} --format "%w %f %e" | \
while read LINE; do
# --format指定した通りに変数に格納
declare -a eventData=(${LINE})
dirPath=${eventData[0]}
fileName=${eventData[1]}
# ファイル名パターンマッチング (マッチしなかったら無視)
[[ $fileName =~ ${FILE_PATTERN} ]] || continue
${COMMAND} "${dirPath}${fileName}"
done
解説
- オプション
-m
をつけないと最初のイベントで終了する。 - オプション
-r
でディレクトリを再帰的に監視 - 後で受け取りやすいように
--format
オプション指定 - bashの正規表現マッチングでファイル名の判定
使い方
watch-file.sh /data/app '^application-data-.*\.csv$' "echo"
フォアグラウンドで実行し続けるので Ctrl+C
で止める。
Redhat系OSのサービス化
inotifywaitはフォアグラウンドで継続実行されるのでsystemdサービスにする。
/usr/lib/systemd/system/watch-file.service
[Unit]
Description=Watch files and archive
[Service]
Type=simple
ExecStart=/path/to/watch-file.sh /data/app '^.*\.csv$' gzip
ExecStop=/usr/bin/kill -QUIT $MAINPID
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
systemctl enable watch-file
systemctl start watch-file
これでZABBIXとかでサービス監視もできるようになる。