Fileの変更を検知して特定のコマンドを実行するAppleScript
必要に駆られてタイトル通りの処理を定期的かつ自動で実行したかったので記録します。
AppleScriptを書くことが初めてだったので各処理の説明もかんたんにまとめておきます(備忘録です)。
何をする?
あるファイルの更新を検知して、特定のコマンドを実効するAppleScriptです。
結論
スクリプトは以下の通り。
日本語で記載している部分を自身の環境に合わせて変更すれば動くはずです。
property interval : 更新間隔(秒)
property checkedFilePath : 更新を検知したいファイルのパス
property mdate : ""
on run
set mdate to (do shell script "date -r " & checkedFilePath & " +%Y:%m:%d:%H:%M:%S")
end run
on idle
my main()
return interval
end idle
on quit
continue quit
end quit
on main()
set mdate_new to (do shell script "date -r " & checkedFilePath & " +%Y:%m:%d:%H:%M:%S")
if not mdate = mdate_new then
display notification "detected modification"
do shell script 特定のコマンド
set mdate to mdate_new
end if
end main
これをスクリプトエディタで保存します。
保存するときに、「ファイルフォーマット」を「アプリケーション」に設定し、「ハンドラの実行後に終了しない」をチェックする必要があります。
各処理の説明
1. 変数の定義
冒頭で必要な変数を定義します。
propertyで定義した変数はグローバル変数のように扱うことができるみたいです[1]。
interval
とcheckedFilePath
は与えておきます。
property interval : 更新間隔(秒)
property checkedFilePath : 更新を検知したいファイルのパス
property mdate : ""
interval: 更新間隔。秒で指定しています。
例:property interval : 60
checkedFilePath: 更新を検知したいファイルのパス
例:property checkedFilePath : "/Users/stktu/Dropbox/xxx.txt"
mdate: 更新を検知したいファイルの更新日時を保存する変数
2. アプリの最初の実行時にファイルの更新日時を取得
on run
set mdate to (do shell script "date -r " & checkedFilePath & " +%Y:%m:%d:%H:%M:%S")
end run
on メッセージ名
からend メッセージ名
までの部分をハンドラと呼びます[2]。
runハンドラはアプリケーションを起動したときに実行されます。
dateコマンドで取得した更新日時をmdate
に保存します。
interval
との兼ね合いもありますが、1秒単位の更新も検知できるように、日時の文字列フォーマットは+%Y:%m:%d:%H:%M:%S
(年:月:日:時:分:秒)で指定しています[3]。
3. 一定間隔で繰り返し実行
on idle
my main()
return interval
end idle
idleハンドラは、何秒かおきにスクリプトを実行する場合に使います。[2:1]
アプリケーションを起動した直後と、その後interval
秒ごとに指定したイベントが実行されます。
ここでは後述のmain()
を実行します。
4. quitハンドラ
quitハンドラでは、必ずcontinue quitを書くと覚えておきましょう。[2:2]
とのことです。詳細は別の記事を参照してください。
on quit
continue quit
end quit
5. ファイルの更新をチェック
on main()
set mdate_new to (do shell script "date -r " & checkedFilePath & " +%Y:%m:%d:%H:%M:%S")
if not mdate = mdate_new then
display notification "detected modification"
do shell script 特定のコマンド
set mdate to mdate_new
end if
end main
main()
では以下の処理を行います。
- 検知対象のファイルの更新日時を取得して
mdate_new
に保存 - 予め取得しておいた
mdate
とmdate_new
とが異なれば、3–5を実行する。そうでなければ処理を終了する。 - "detected modification"という通知を表示する。
- 特定のコマンドを実行する。
-
mdate
をmdate_new
に置き換える。
mdate_new
に保存される更新日時の形式はmdate
と同じです。
監視対象のファイルが更新されたら、mdate_new
とmdate
が異なっている(not mdate = mdate_new
が真になる)ので、上記処理3–5が実行されます。
特定のコマンドはAppleScriptでもいいですし、コマンド、シェルスクリプトでも構いません。
例えば、監視対象のファイルをコピーするのであれば以下のように書きます。
(文字列は&
で結合できます)
set newFilePath to ファイルのコピー先パス
do shell script "cp " & checkedFilePath & " " & newFilePath
さいごに
AppleScrpt、色々な操作を自動化できそうで便利だなと感じました。
はじめて書いたスクリプトなので、おかしい所やもっといい書き方があれば教えてもらえると嬉しいです。
Discussion