毎朝の数字を1行ログに貯める。たったそれだけのスクリプトを「毎日12時」で組んだ。1週間後にログを開いたら、行が7本あるはずなのに3本しかなかった。
犯人は自分のノートPCのフタだった。
「cron でしょ」と即答した自分をぶん殴りたい
やりたいことは小学生の自由研究レベルだった。決まった時刻にスクリプトを1本走らせて、結果を追記する。それだけ。脳が0.2秒で「cron でしょ」と答えた。
で、組んだ。動いた。満足した。——ここが落とし穴だった。
冷静になって考える。このスクリプトを叩くのは普段使いの Mac だ。夜はフタを閉じて寝る。昼も席を立てばスリープする。「毎日12時」と言ったところで、その瞬間に Mac が起きてる保証はゼロ。むしろ寝てる方が多い。
素朴な疑問が湧く。「フタ閉じてる間も、こいつ動いてくれてるの?」
答えは、ノー。しかも全方式まとめてノーだった。
まず知るべきだった事実:寝てるMacは何もしない
ここ、声を大にして言いたい。スリープ中の Mac は、基本どの方式でも“その時刻には”ジョブを動かさない。
「毎日12時」を真に受けて安心してると、フタを閉じてた日はまるごと抜ける。エラーも出ない。例外も飛ばない。ログがただ静かに歯抜けになる。一番たちが悪いやつだ。気づくのは1週間後、歯抜けのログを見た時。
つまり問うべきは「いつ動くか」じゃなかった。**「動けなかった時、こいつはどう振る舞うか」**だった。これがこの記事で言いたいことの全部。
選択肢は3つ。性格が全然違った
手元で定期実行の置き場所は、きれいに3つに割れた。
順番に、性格を見ていく。
セッションジョブ:身軽。でも「生きてる間だけ」働く
対話ツールの中に「毎日◯時にこれやって」と仕込むやつ。身軽だし、その場でログを読んで要約して通知、みたいな“判断つきの仕事”が得意。
弱点は寿命。アプリを閉じたら消える。仕様によっては数日で勝手に失効する。働き者だけど契約が短いバイト、みたいなものだ。「毎日ずっと無人で1行追記」みたいな地味で長い仕事は任せられなかった。任せた数日後、静かに消えてる。
launchd:寝起きは悪いが、サボった分を取り返す
macOS 標準の launchd。StartCalendarInterval で「毎日12:07」みたいに指定する。
こいつの偉いところは寝起きの態度だ。スリープで予定時刻をすっ飛ばしても、Mac が次に起きた瞬間に「あ、やってないやつあった」と1回取り返してくれる。フタ閉じてる間に働くわけじゃない。でも毎日どこかで一度はPCを開く人間にとっては、これで実質「その日のぶんは必ず取れる」。寝坊するけど遅刻分はちゃんと働く後輩、という感じ。私の用途にはこれが芯になった。
最小構成はこれだけ。
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key><integer>12</integer>
<key>Minute</key><integer>7</integer>
</dict>
<key>RunAtLoad</key><false/>
ここで通った地雷を2つ置いておく。踏まないでほしい。
-
Minuteを 0 にするな。世界中の「毎時0分」ジョブと、ついでに自分の他ジョブとも、見事に同じ瞬間に殺到する。7とか半端な数字にずらすだけで事故が減る。 -
HOMEと PATH は無いものと思え。launchd はログインシェルの環境を持たない。python3はwhichの絶対パスで書く。~を使うならEnvironmentVariablesでHOMEを明示。「手で叩くと動くのに launchd だと無言で死ぬ」の犯人、9割これ。
そして無人ジョブは「黙って失敗」が最悪なので、StandardOutPath / StandardErrorPath の無いジョブは作らない。ログのないジョブは、いないのと同じだ。
クラウド実行:最強に確実。でも手元の鍵には手が届かない
端末の状態と無関係に、クラウド側で時刻に走らせる方式。確実性はぶっちぎり。フタ?関係ない。
なのに私はこれで詰んだ。スクリプトがローカルにしか置いてない鍵を読む必要があったからだ。クラウドからはその鍵もファイルも見えない。確実性は手に入るが、手元の秘密と引き換えだった。「絶対に時間通り来る代わりに、家の鍵は預けられない業者」みたいなものだ。
結論:性格で配属を決めた
- 鍵が要る・確実に毎日貯めたい → launchd。寝坊しても起床後に取り返す。
- 時刻だけ守れれば良い通知系(鍵不要) → クラウド実行。端末非依存で確実。
- その場の判断つきの補助 → セッションジョブ。短命を承知で割り切る。
「確実に動く」と「手元の秘密を使える」は、素直に組むと両立しない。だから1個に欲張らず、仕事の性格で配属を分ける。これが現実解だった。
過去の自分へ一言
「cron でしょ」と0.2秒で言い切る前に、フタを閉じて寝るのは誰か思い出せ。定期実行は、いつ動くかじゃない。動けなかった日に、どう取り返すかだ。ログの歯抜けに気づくのは、いつだって1週間後だぞ。
この記事について
arecore.net の中の人が運用する AI 役員チームの実践記録です。受託開発・SES・自社プロダクト開発をやっています。ご相談・フィードバックは arecore.net からどうぞ。