ShellScript
MacOSX

ファイルの変更を定期的に監視して、特定のコマンドを実行するシェルスクリプト

More than 1 year has passed since last update.


GruntとかGulpとか使わずにファイル監視して、コマンドを実行したい!

ファイルを監視してくれるスクリプトはとても便利です! でも、何もインストールせずにやってみたい。

今回はShell Scriptでやってみます。


指定したファイルの更新があったらコマンドを自動実行するシェルスクリプト

指定したファイルの更新があったらコマンドを自動実行するシェルスクリプトを参考にMac OSXでも使えるようにしました。


ファイル監視の動機

ファイル監視(いわゆるwatch)をShell Scriptでやってみようと思って調べたのが動機です。OMakeなどを使えば、ファイルを監視してmakeを行うことができるようですが、インストールせずに似たようなことができないかと興味を持ちました。


動作確認した環境


  • Mac OSX(10.11.3)

  • Gnu bash version 3.2.57(1)-release-(x86_64-apple-darwin15)


タイムスタンプではなく、ハッシュ(SHA256)で更新を監視

参考にした記事では、タイムスタンプを使ってファイルの監視を行っていました。この記事では、ハッシュ値を元に更新の監視を行います。ハッシュには、OpenSSLのSHA256を用いました。


ファイルの監視

指定したファイル(第一引数)を一秒間隔で監視します。ファイルのハッシュ値が以前と異なるなら、はじめに指定したコマンド(第二引数)を実行します。コマンドはクォーテーションで囲んでください。実行権限を渡すのを忘れずに(chmod +x ./mywatch.sh)。


mywatch.sh

#!/bin/sh

# see also http://mizti.hatenablog.com/entry/2013/01/27/204343
usage() {
echo "実行するには2個の引数が必要です。
第一引数: 監視対象ファイル名
第二引数: 監視対象ファイルが更新された際に実行されるコマンド
例: ./autoexec.sh a.cpp 'g++ a.cpp && ./a.cpp'"

}
update() {
echo `openssl sha256 -r $1 | awk '{print $1}'`
}
if [ $# -ne 2 ];
then
usage
exit 1
fi

INTERVAL=1 #監視間隔, 秒で指定
no=0
last=`update $1`
while true;
do
sleep $INTERVAL
current=`update $1`
if [ "$last" != "$current" ];
then
nowdate=`date '+%Y/%m/%d'`
nowtime=`date '+%H:%M:%S'`
echo "no:$no\tdate:$nowdate\ttime:$nowtime\tfile:$1"
eval $2
last=$current
no=`expr $no + 1`
fi
done



使い方

./mywatch.sh filename 'command'



  • filename:監視対象となるファイルの名前


  • command:変更時に実行するコマンド(例: make)

注意:commandはシングルクォーテーションで囲んでください


./mywatch.sh ./index.html 'echo [[FILE WAS UPDATED]]'

index.htmlを変更すると…以下のように表示されて与えたコマンド(echo [[FILE WAS UPDATED]])が実行されていることが確認できます。

scsho.png


用途

gruntとかgulpとか使わなくても済むような趣味プログラミングで使えそうです。小さいC言語プログラムとか。makeとかに組み込めないかな……(意地でもgruntとか使わない作戦)


参考文献(元ネタ)