目次
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 -lint と StandardErrorPath のログを見るのが近道です。
参考文献
Creating Launch Daemons and Agents - Apple Developer (2026-05-07 アクセス) ↩︎
launchd.plist(5) - manpagez (2026-05-07 アクセス) ↩︎ ↩︎
LAUNCHCTL Command - SS64 (2026-05-07 アクセス) ↩︎
