手元PC(mac)で、スクリプトを定期実行したいときにどうするんだろう?という気持ちになり、いろいろ調べたところcronとかではなくてlaunchdを使ったら良さそうらしいと知ったのでメモ。
定期実行をlaunchdを使って登録する
launchdで定期的にスクリプトを実行 - Qiita が非常に参考になる。基本的にはStartIntervalかStartCalendarIntervalを使ったらcronのように定期実行ができる。例えば10分に一回実行したかったらこんな感じ。
~/Library/LaunchAgents/com.github.shibayu36.mycommand.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>com.github.shibayu36.mycommand</string> <key>ProgramArguments</key> <array> <string>/path/to/mycommand</string> </array> <key>StartInterval</key> <integer>600</integer> <key>StandardOutPath</key> <string>/Users/shibayu36/log/mycommand.log</string> <key>StandardErrorPath</key> <string>/Users/shibayu36/log/mycommand.err.log</string> </dict> </plist>
これで後はこのplistファイルをlaunchctl loadすると定期実行ができる。
launchctl load ~/Library/LaunchAgents/com.github.shibayu36.mycommand.plist
他にも
- cronの10,20,30のように複数指定したい場合については launchdの時刻指定を複数時刻にしたい - 別館 子子子子子子(ねこのここねこ)はてブロ部 が参考になる
- plistをより詳細に知りたければ
man launchd.plist
が参考になる
どうデバッグするか
上記設定を登録するにあたって、なかなかうまく動作しなくて困った。そこでどうデバッグしていったかも書いておく。
- 定期実行設定の場合でも、その時間まで待たなくとも、launchctl start ...を使えば実行できる
launchctl load ~/Library/LaunchAgents/com.github.shibayu36.mycommand.plist
していたら、Label指定でスクリプト実行できる。例:launchctl start com.github.shibayu36.mycommand
- スクリプトまでも起動できていないようなときは
/var/log/system.log
あたりにログが出ている - スクリプトが実行されてエラーで落ちる場合はSTDERRの内容がStandardErrorPathで設定した場所に出力されている
今回僕が設定するにあたっては以下の点にハマっていた。
- PATHが通常のターミナルを使っているときと違うので、コマンドが見つからないエラーになっていた
- StandardOutPath、StandardErrorPathあたりの出力先がroot権限になっていて書き込み出来なかった
- ログが非常に分かりづらくて悩んだ...
- たぶん https://qiita.com/harada4atsushi/items/f185d7524b1416c1699b あたりと同じ問題
まとめ
今回はコマンド定期実行のためにlaunchdについて軽く調べた。いつもhomebrewとかで入れたミドルウェアとかを説明を見たままにlaunchctlで登録していたので、この辺の理解が深まってよかった。