$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

macでの定期実行はcronじゃなくてlaunchdを使う

手元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

他にも

どうデバッグするか

上記設定を登録するにあたって、なかなかうまく動作しなくて困った。そこでどうデバッグしていったかも書いておく。

  • 定期実行設定の場合でも、その時間まで待たなくとも、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権限になっていて書き込み出来なかった