PR表記: 当記事にはアフィリエイトリンクが含まれます。商品の購入は自己判断でお願いします。
macOSでスクリプトを定期実行したい場合、launchdが標準的な方法です。Linuxのcronに相当する仕組みですが、macOSではlaunchdの利用が推奨されています。この記事では、plistファイルの書き方からデバッグまで、実用的な内容を解説します。
launchdとは
launchdはmacOSのプロセス管理デーモンです。OS起動時にサービスを立ち上げたり、指定した時刻にスクリプトを実行したりできます。
plist(Property List)ファイルに設定を書き、~/Library/LaunchAgents/ に配置することで、ユーザーレベルのジョブを登録できます。
cronとの違い
| 項目 | cron | launchd |
|---|---|---|
| macOS推奨 | 非推奨 | 推奨 |
| スリープ復帰後 | 実行されない | 実行される |
| ログ管理 | 自分で設定 | 標準で対応 |
| 設定形式 | crontab | plist (XML) |
launchdの大きなメリットは、Macがスリープしていて実行タイミングを逃した場合でも、復帰後に実行してくれる点です。
基本的なplistの書き方
例: 毎日9時にPythonスクリプトを実行
<?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-script</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/python3</string>
<string>/Users/yourname/scripts/daily_task.py</string>
</array>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>9</integer>
<key>Minute</key>
<integer>0</integer>
</dict>
<key>StandardOutPath</key>
<string>/tmp/daily-script-out.log</string>
<key>StandardErrorPath</key>
<string>/tmp/daily-script-err.log</string>
<key>WorkingDirectory</key>
<string>/Users/yourname/scripts</string>
</dict>
</plist>
各キーの説明
- Label: ジョブの一意な識別子。逆ドメイン形式が慣例
- ProgramArguments: 実行するコマンドと引数を配列で指定
- StartCalendarInterval: 実行タイミング(時刻指定)
- StandardOutPath / StandardErrorPath: ログの出力先
- WorkingDirectory: スクリプト実行時の作業ディレクトリ
plistの配置と登録
1. ファイルを配置
cp com.example.daily-script.plist ~/Library/LaunchAgents/
2. ジョブを登録
launchctl load ~/Library/LaunchAgents/com.example.daily-script.plist
3. 即時実行でテスト
launchctl start com.example.daily-script
4. ジョブを停止・削除
launchctl unload ~/Library/LaunchAgents/com.example.daily-script.plist
実践例: 定期バックアップスクリプト
特定のフォルダを毎日23時にバックアップするスクリプトの例です。
#!/bin/bash
# backup.sh
SOURCE="$HOME/Documents/important"
DEST="$HOME/Backups/$(date +%Y%m%d)"
mkdir -p "$DEST"
rsync -av --delete "$SOURCE/" "$DEST/"
echo "Backup completed: $(date)" >> /tmp/backup.log
このスクリプト用のplistでは、ProgramArguments に /bin/bash とスクリプトパスを指定し、StartCalendarInterval で Hour=23, Minute=0 を設定します。
間隔実行(StartInterval)
時刻ではなく一定間隔で実行したい場合は StartInterval を使います。
<key>StartInterval</key>
<integer>3600</integer>
上記は3600秒(1時間)ごとに実行する設定です。
デバッグのコツ
ログを確認する
# 標準出力ログ
cat /tmp/daily-script-out.log
# エラーログ
cat /tmp/daily-script-err.log
launchdのシステムログ
log show --predicate 'subsystem == "com.apple.xpc.launchd"' --last 1h
よくあるトラブルと対処法
- パスが通っていない: plistから実行されるスクリプトではPATHが最小限。Pythonやコマンドはフルパスで指定する(例:
/usr/bin/python3) - 権限エラー: スクリプトに実行権限を付与する
chmod +x script.sh - 環境変数が読まれない:
.zshrc等は読まれないので、必要な環境変数はplist内のEnvironmentVariablesキーで設定する - plistのXML構文エラー:
plutil -lint file.plistで検証できる
plistの構文チェック
plutil -lint ~/Library/LaunchAgents/com.example.daily-script.plist
エラーがあれば具体的な行番号が表示されるので、修正の手がかりになります。
複数スケジュールの設定
曜日指定や複数時刻の実行も可能です。
<key>StartCalendarInterval</key>
<array>
<dict>
<key>Weekday</key>
<integer>6</integer>
<key>Hour</key>
<integer>8</integer>
<key>Minute</key>
<integer>30</integer>
</dict>
<dict>
<key>Weekday</key>
<integer>0</integer>
<key>Hour</key>
<integer>8</integer>
<key>Minute</key>
<integer>30</integer>
</dict>
</array>
Weekdayは0=日曜、6=土曜です。上記は土日の8:30に実行する設定です。
まとめ
launchdはmacOSで定期実行を設定する標準的な方法です。plistの書き方さえ覚えれば、バックアップ・データ収集・通知送信など、さまざまなタスクを自動化できます。cronよりもスリープ復帰への対応が優れているため、Mac環境ではlaunchdを使いましょう。
Mac以外も含めた自動化全般の記事は、AI副業ラボでも公開しています。
よくある質問(FAQ)
Q1: cronはmacOSで使えないのですか?
cronはmacOSでも動作しますが、Apple公式にはlaunchdの利用が推奨されています。cronではMacスリープ中に実行タイミングを逃すと復帰後に実行されませんが、launchdは復帰後に自動実行されるメリットがあります。
Q2: plistの変更を反映するにはどうすればいいですか?
plistを編集した後は、launchctl unload で一度アンロードしてから launchctl load で再読み込みする必要があります。ファイルを上書きしただけでは反映されません。
Q3: launchdで実行したスクリプトのログはどこに出ますか?
plistの StandardOutPath と StandardErrorPath で指定したファイルに出力されます。指定しない場合はログが捨てられるため、デバッグ時は必ず設定しておきましょう。
参考書籍: macOSの仕組みを深く理解したい方に。
