launchd.plist の書き方


Mac で cron ぽい事をしたい場合、 launchd を使う。
以下は、 anything-filelist 〜すべてのファイルを瞬時に開く方法〜 - http://rubikitch.com/に移転しました で解説されている、 Emacsプラグイン Anything で使用するファイルリストの更新を、 cron のかわりに launchd で行う設定。


下記のファイルを作成し、 launchctl コマンドの load で登録する。


~/Library/LaunchAgents/emacs-anything-make-filelist.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>emacs-anything-make-filelist</string>
    <key>ProgramArguments</key>
    <array>
        <string>ruby</string>
        <string>/Users/progd/source/make-filelist.rb</string>
        <string>~</string>
    </array>
    <key>StartCalendarInterval</key>
    <dict>
        <key>Minute</key>
        <integer>0</integer>
    </dict>
    <key>StandardOutPath</key>
    <string>/tmp/all.filelist</string>
</dict>
</plist>
$ cd ~/Library/LaunchAgents/
$ launchctl load emacs-anything-make-filelist.plist


エラー等が発生した場合、 Console.app で出力内容を確認できる。

設定の意味

ProgramArguments の array 以下の string 要素に実行するコマンドを記述する。
コマンドに与える引数は、別の string 要素にする必要がある。*1


StartCalendarInterval の dict 以下の要素は、 key と integer の組を、 cron の要領で指定する。
上記の例では、毎時 0 分、 1 時間ごとにジョブが実行される。
dict を空にすると、1 分ごとに実行されるようになる。


man 5 launchd.plist より抜粋:

StartCalendarInterval 
     This optional key causes the job to be started every calendar interval as speci-
     fied. Missing arguments are considered to be wildcard. The semantics are much
     like crontab(5).  Unlike cron which skips job invocations when the computer is
     asleep, launchd will start the job the next time the computer wakes up.  If mul-
     tiple intervals transpire before the computer is woken, those events will be
     coalesced into one event upon wake from sleep.
     このオプションのキーは指定された各カレンダーインターバルでジョブを起動します。
     省略された引数は、ワイルドカードとみなされます。文法は crontab(5) に非常に似ています。
     コンピューターがスリープしている場合、cron はジョブの起動をスキップしますが、
     launchd は次回コンピューターが復帰した時にジョブを起動します。
     コンピューターが復帰する前に、複数のインターバルが発生した場合、
     それらは復帰直後に一つのイベントに結合されます。


StandardOutPath は、シェルでリダイレクトをするように、標準出力を保存したいファイルパスを指定する。

注意

登録済みの plist ファイルを編集しても変更は適用されない。一度 unload してから登録し直すこと。

$ launchctl unload emacs-anything-make-filelist.plist && launchctl load emacs-anything-make-filelist.plist


参考: cronからlaunchdへ(より効率的なジョブ管理を目指して) - ザリガニが見ていた...。

*1:通常のコマンドのように、ひとつの string 要素内にスペース区切りで記述すると、要素全体がコマンドとして扱われてしまうようだ。上記の例をスペース区切りで記述した場合 posix_spawn("ruby /Users/progd/source/make-filelist.rb ~", ...): No such file or directory というエラーとなる