ども、初老丸です。

tl;dr

Python で watchdog というモジュールが個人的にホットでこのモジュールを使って、ファイル作成を検知したら任意のアクションを起こすツールをサクッと作ってみたりしたが、よくよく調べてみると watchdog に同梱されている watchmedo というツールが既に存在しているので触ってみた。

試す

試した環境

$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.2 LTS"

$ python -V
Python 2.7.6

インストールとヘルプ

  • ひとまず pip でインストール
$ pip install watchdog

watchdog のバージョンは watchdog-0.8.3 を前提に。

  • ヘルプ
$ watchmedo --help
usage: watchmedo [-h] [--version]
                 {tricks-from,tricks-generate-yaml,log,shell-command,auto-restart}
                 ...

positional arguments:
  {tricks-from,tricks-generate-yaml,log,shell-command,auto-restart}
    tricks-from         Subcommand to execute tricks from a tricks
                        configuration file. :param args: Command line argument
                        options.
    tricks-generate-yaml
                        Subcommand to generate Yaml configuration for tricks
                        named on the command line. :param args: Command line
                        argument options.
    log                 Subcommand to log file system events to the console.
                        :param args: Command line argument options.
    shell-command       Subcommand to execute shell commands in response to
                        file system events. :param args: Command line argument
                        options.
    auto-restart        Subcommand to start a long-running subprocess and
                        restart it on matched events. :param args: Command
                        line argument options.

optional arguments:
  -h, --help            show this help message and exit
  --version             show program's version number and exit

Copyright 2011 Yesudeep Mangalapilly .
Copyright 2012 Google, Inc.

Licensed under the terms of the Apache license, version 2.0. Please see
LICENSE in the source code for more information.

ロギング

watchmedo で対象のディレクトリで発生するイベントをロギングしてみる。ロギングしたい場合には以下のように実行する。

$ watchmedo log --recursive --patterns "*.txt;*.png" ./test01/
  • log オプションでイベントのロギングを開始する
  • --recursive オプションでディレクトリを再帰的に監視
  • --patterns オプションで監視対象ファイルの拡張子を複数指定
  • 最後に監視対象ディレクトリ(./test01/)を指定

その他にもオプションがあるので詳細は watchmedo log --help にて確認したい。

せっかくなのでデモ動画。

コマンド実行

ロギングに続いて、ディレクトリイベントをトリガにしてコマンドを実行してみる。

$ watchmedo shell-command --recursive --patterns '*.txt;*.png' --command 'echo ${watch_src_path}' ./test01/
  • shell-command オプションで --command で指定したコマンドを実行する
  • --command オプションではいくつかの変数が使える(後述)
  • --recursive--patternslog オプションと同じ

その他にもオプションがあるので詳細は watchmedo shell-command --help にて確認したい。

ちなみに、--command オプションで利用できる変数は以下の通り。

  • ${watch_event_type}
  • ${watch_object}
  • ${watch_src_path}
  • ${watch_dest_path}

それぞれを echo した場合は以下の通り。

#
# touch test01/test01.txt
# mv test01/test01.txt test01/test02.txt
# echo "foo" >> test01/test02.txt
# mv test01/test02.txt /tmp/
#
$ watchmedo shell-command --recursive --patterns '*.txt;*.png' --command 'echo "${watch_event_type} | ${watch_object}"' ./test01/
created | file
modified | file
moved | file
modified | file
deleted | file

#
# touch ./test01/test12345.txt を実行した場合
#
$ watchmedo shell-command --recursive --patterns '*.txt;*.png' --command 'echo ${watch_src_path}' ./test01/
./test01/test12345.txt
./test01/test12345.txt

#
# echo "test" >> ./test01/test12345.txt
# mv ./test01/test12345.txt ./test01/test7890.txt を実行した場合
#
$ watchmedo shell-command --recursive --patterns '*.txt;*.png' --command 'echo ${watch_dest_path}' ./test01/
./test01/test7890.txt

この shell-command オプションを利用することで、監視対象ディレクトリにファイルを保存したタイミングで別のストレージ(例えばリモートの NFS サーバー)やオブジェクトストレージ(例えば Amazon S3 とかに)に保存等を行わせることが出来そう。

あと watchmedo Tricks って…

なんぞや。あとで調べよっと。

以上

同様のスクリプトを作っておかげで watchmedo の理解も進んだ気がする。

やりたい事は watchmedo で実現できそうな気がするが、shell-command を利用した際の他のコマンドとの連携とか気になるところ。引き続き、触っていきたい。

元記事はこちら

watchmedo が便利だと思ったのでメモ