ファイル/ディレクトリの変更に応じて任意のジョブを実行するincron

 Linuxにてジョブのスケジューリングを行う定番ツールであるcronについては、その機能と活用法を詳細に解説した多数のドキュメント、チュートリアル、ガイドの類が存在しており、今更特に説明する必要はないだろう。こうした伝統的なcronで行えるのが時刻指定型のジョブ実行であるのに対して、ファイルシステムの変更を検出して指定のコマンドを実行させるというコンセプトで作られたcronクローンの一種に incron というツールが存在する(正式名称はinotify cron)。incronを使用するための設定としては、どのようなファイル/ディレクトリの変更を監視対象とするかおよび、そこでの変更発生時に実行すべきジョブの登録が必要となる。

 Fedoraユーザの場合はyumを介したincronのインストールが行えるようになっており、具体的には「yum install incron」というコマンドを実行すればいい。インストール後に行うべき作業は、incronデーモンの起動および、それに引き続くジョブのスケジューリング設定である。それにはまずroot権限を取得し「service incrond start」コマンドの実行によりincronデーモンを起動させ、次にブート時の自動起動を設定させるための「chkconfig incrond on」コマンドを実行しておく。

 この場合のジョブのスケジューリングは、crontabと同様のincrontabと呼ばれるコマンドを介して、テーブルファイルへの登録をする仕様となっている。incrontabで登録する各行には、個々のファイル名に続けて、監視対象とするファイルシステムの変更イベントをコンマ区切りで一覧したリストおよび、当該イベントの発生時に実行すべきコマンドを記述すればいい。こうして登録しておいたジョブは、指定しておいたファイルやディレクトリの変更をトリガとして実行されることになる。incronにてモニタ可能なファイルシステムの全イベントを確認したければ、「incrontab -t」コマンドを使用すればいい。下記に一覧したものがこうして作成されるリストであるが、ここには個々の説明が並記してある。

  • IN_ACCESS:当該ファイルがアクセスされた
  • IN_MODIFY:当該ファイルが変更された
  • IN_ATTRIB:メタデータが変更された(パーミッション、拡張属性、タイムスタンプなど)
  • IN_CLOSE_WRITE:書き込み可能ファイルの1つが閉じられた
  • IN_CLOSE_NOWRITE:書き込み不可能ファイルの1つが閉じられた
  • IN_OPEN:ファイルの1つが開かれた
  • IN_MOVED_FROM:当該ディレクトリの外にファイルが出された
  • IN_MOVED_TO:当該ディレクトリの中にファイルが入れられた
  • IN_CREATE:当該ディレクトリ中にファイル/ディレクトリが新規作成された
  • IN_DELETE:当該ディレクトリ中からファイル/ディレクトリが削除された
  • IN_DELETE_SELF:当該ファイル/ディレクトリ本体が削除された
  • IN_CLOSE:IN_CLOSE_WRITEとIN_CLOSE_NOWRITEの双方を対象とする
  • IN_MOVE:IN_MOVED_FROMとIN_MOVED_TOの双方を対象とする
  • IN_ALL_EVENTS:ここに一覧した全イベントを対象とする
  • IN_DONT_FOLLOW:シンボリックリンクは参照させない
  • IN_ONLYDIR:当該パスがディレクトリの場合のみ監視させる
  • IN_MOVE_SELF:当該ファイル/ディレクトリ本体が移動された

 例えば、各自のhomeディレクトリ中にファイルやディレクトリが新規作成された時点で指定のオーディオファイルを自動再生させたいという場合は、「/home/linuxlala IN_CREATE paplay /usr/share/sounds/pop.wav」といったincrontabのエントリを登録しておけばいい。同じく「/home/linuxlala IN_CREATE rm -rf $@/$#」も同様のイベントをトリガとして実行されるエントリだが、この場合は少々悪質な操作が行われることになる。つまりこのエントリをincrontabファイルに登録しておくと、当該ユーザのhomeディレクトリで何らかのディレクトリやファイルが作成された段階で、それらは即座に削除されてしまうのだ。実はこの場合、ワイルドカードと呼ばれる特殊な記号($@/$#)を用いることによって、新規に作成されたファイル/ディレクトリのフルパスをrm -rfコマンドに渡しているのである。

 より実用的な用途にてこうしたワイルドカードが役立つのは、実行したいスクリプトやコマンドにファイル名の情報を渡したいという場合であろう。例えば、指定されたファイル中から“呪いの言葉”(curse word)を削除するスクリプトが手元にあり、/home/linuxlala/Documentsディレクトリに作成されるファイルはすべてその処理対象としたいという場合は、「/home/linuxlala/Documents IN_CLOSE_WRITE /home/linuxlala/replace_curse_words.sh $@/$#」というincrontabエントリを用意しておけばいいことになる。なおこのエントリではIN_CREATEではなくIN_CLOSE_WRITEを指定しているが、これはIN_CREATEイベントはディレクトリであっても生成されるのに対して、IN_CLOSE_WRITEはファイルのみが対象となるからである。

 $@と$#のワイルドカードは、監視対象とされるファイルのパスおよび当該イベントに関係したファイル名をそれぞれ返すものだが、その他にもイベントフラグをテキストおよび数値形式で処理する$%や$&などのワイルドカードも利用することができる。

 なおincrontabファイルの内容を書き換えた場合は、「incrontab -d」コマンドを実行してユーザテーブルをリロードさせておく必要がある。このアップデートを行わなかった場合は、変更前の指定に基づいたincronの処理が実行され続けることになる。

 このように多様な処理が行えるincronだが、現行バージョンでは対処できない処理もいくつか存在している。例えば私が試した限り、新規に作成したファイルをGeditで開かせるという処理はすべて失敗してしまった。その際に設定したエントリは「/home/linuxlala IN_CLOSE_WRITE gedit $@/$#」というものである。これと同様の、指定イベントをトリガにしてincronにアプリケーションを起動させるという処理は、すべてのグラフィカルアプリケーションで失敗している。つまりファイルの新規作成あるいは削除や移動時に、Gedit、Akregator、gnome-terminalなどを起動させるエントリを各種記述してみたのだが、これらのアプリケーションは一向に起動してくれないのだ。

 次に少し発想を変えて、homeディレクトリでの新規ディレクトリ作成時にGeditを介して当該ディレクトリ中にquotes.txtというファイルを作成させる「/home/linuxlala IN_CREATE gedit /home/linuxlala/quotes.txt」というエントリをincronに処理させることにしてみた。ところが結局のところ、この処理もうまく動作しなかったのである。同様に/usr/bin/geditといったグラフィカルアプリケーションのフルパスを指定しても結果は改善されなかった。その一方でincronを介した各種スクリプトの呼び出し、コマンドに対するファイル名の引き渡し、mplayerによるオーディオ/mp3ファイルの演奏開始などは、すべて問題なく処理されているのである。このようにグラフィカルアプリケーションを上手く扱えない理由については、開発者に問い合わせてみたものの今のところ返事はもらえていない。

 incronは小型ながらも大きな将来性を期待させるユーティリティなのだが、現行バージョンではグラフィカルアプリケーションに未対応であったり再帰的な処理ができないなど、若干の問題点が残されている。しかもincronがディレクトリ階層を再帰的に監視できない点については、かなり以前からTO-DOリストに掲載されたままになっているのだ。こうした現行のincronに対する私個人の評価は、コンセプト的には優れているものの、メインストリームのツールとなるには今一歩の開発努力が必要というものである。

Shashank Sharmaは、フリー/オープンソース系ソフトウェアの初心者向け記事の執筆およびLinux.comフォーラムボードの管理を行なっており、Apress社から刊行されている『Beginning Fedora』の共著者でもある。

Linux.com 原文