macOSのlaunchdで定期実行を設定する手順とよくあるエラー対処

公開日:
目次

macOSで定期実行を仕込む場合、cronよりもlaunchdが公式に推奨されています[1]。ただし、plistの書き方や launchctl のサブコマンドで詰まることが多いのも事実です。この記事では、~/Library/LaunchAgents/ にplistを置いてジョブを登録するまでの最小手順と、よくあるエラーへの対処をまとめます。

launchdとcronの違い

macOSにはcronも残っていますが、Appleはlaunchdを推奨しています。理由は次のとおりです。

  • cronは互換性のために残っているだけで、メンテナンスはほぼされていない
  • launchdはスリープ復帰時のジョブ再実行を考慮できる[2]
  • ログ出力先や環境変数をplistで明示的に制御できる

ユーザー単位のジョブは LaunchAgents、システム全体のジョブは LaunchDaemons として定義します。個人利用なら LaunchAgents で十分です。

plistファイルの作成

~/Library/LaunchAgents/com.example.daily-task.plist を作成します。com.example.daily-task の部分は逆ドメイン形式で一意にします。

<?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.example.daily-task</string>

  <key>ProgramArguments</key>
  <array>
    <string>/bin/bash</string>
    <string>-lc</string>
    <string>/path/to/your-script.sh</string>
  </array>

  <key>StartCalendarInterval</key>
  <dict>
    <key>Hour</key>
    <integer>15</integer>
    <key>Minute</key>
    <integer>20</integer>
  </dict>

  <key>StandardOutPath</key>
  <string>/tmp/daily-task.log</string>

  <key>StandardErrorPath</key>
  <string>/tmp/daily-task.err</string>
</dict>
</plist>

押さえておきたいポイントは3つです。

  • Label はファイル名と一致させる
  • ProgramArguments/bin/bash -lc "..." の形にすると、ログインシェルのPATHが読めて環境変数が通る
  • 時刻指定は StartCalendarInterval、N秒ごとなら StartInterval を使う[2:1]

ジョブの登録と起動

Big Sur 以降は bootstrap / bootout を使うのが安全です[3]

# 登録
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.example.daily-task.plist

# 即座に1回実行して動作確認
launchctl kickstart -k gui/$(id -u)/com.example.daily-task

# 状態確認
launchctl print gui/$(id -u)/com.example.daily-task

# 解除
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/com.example.daily-task.plist

旧コマンドの launchctl load / launchctl unload も動きますが、Big Sur 以降のドキュメントでは bootstrap / bootout が標準です。

よくあるエラー

launchdのジョブ登録や実行で頻繁に出るエラーをまとめます。

Bootstrap failed: 5: Input/output error

plistの構文エラーが原因です。次のコマンドで検証できます。

plutil -lint ~/Library/LaunchAgents/com.example.daily-task.plist

OKなら OK と表示され、構文エラーがあれば該当行が出ます。

スケジュールどおりに実行されない

PATHが通っていないケースが大半です。launchdは最小限の環境で動くため、/usr/local/bin などにあるコマンドが見えません。

対処は2つあります。

  • ProgramArguments/bin/bash -lc "..." にしてログインシェルの環境を読ませる
  • 実行するコマンドはフルパスで書く

それでも動かない場合は StandardErrorPath のログを確認します。

Load failed: 5

ファイルの所有者やパーミッションが原因のことが多いです。次の値に揃えると通ります。

chmod 644 ~/Library/LaunchAgents/com.example.daily-task.plist
chown $(id -u):$(id -g) ~/Library/LaunchAgents/com.example.daily-task.plist

まとめ

macOSの定期実行はcronでも動きますが、launchdに切り替えると環境変数とログの扱いが安定します。手順は「plistを作る → bootstrap で登録 → kickstart で動作確認」の3ステップです。エラーが出たときは plutil -lintStandardErrorPath のログを見るのが近道です。

参考文献

脚注
  1. Creating Launch Daemons and Agents - Apple Developer (2026-05-07 アクセス) ↩︎

  2. launchd.plist(5) - manpagez (2026-05-07 アクセス) ↩︎ ↩︎

  3. LAUNCHCTL Command - SS64 (2026-05-07 アクセス) ↩︎