Gururi.log

id:Gururiの記録です。

Mavericksで定期的に実行されるスクリプトの設定を修正

毎日/毎週/毎月定期的に実行されるスクリプト

職場のサーバがめでたく*1全てMavericks Server搭載のmac mini Serverに更新されたのだが、
Mavericksになって設定が変わったようで、変なタイミングで実行されるようになってしまった。それを修正したのでメモ。

どう変わったか?

今回問題にしているのは、/etc/periodic/{daily|weekly|monthly}/に置かれたスクリプトを定期的に実行する設定。これは過去の(Mac)OS Xでも同じ*2なのだが、設定が異なっている。
Mountain Lionまでは

daily 毎日3:15
weekly 毎週土曜日3:15
monthly 毎月1日5:30

だったのが、Mavericksでは

daily 86,400秒*3ごとに1回
weekly 604,800秒*4ごとに1回
monthly 2629746秒ごと*5に1回

となってしまった。何時に起動する、という指定ではなくなっている。指定されているのは実行間隔で、このためにあらぬ時刻に実行されていた。職場のサーバではログローテートやプロキシサーバの集計を行っているのでこれはまずい。

どう直したか

Mountain Lion以前と同じ設定に直せればいいや、ということで、それを目標とした。

設定の確認

とにもかくにも、今と以前の設定を確認するところからスタート。設定ファイルは、MavericksでもMountain Lionでも、 /System/Library/LaunchDaemons/com.apple.periodic-{dai|week|month}ly.plist であるので、これの中身を確認する。sudo -sでrootになり、defaultsコマンドで確認してみる。例示はdailyのものである。

実行するコマンド
defaults read /System/Library/LaunchDaemons/com.apple.periodic-daily

Mountain Lionまでの設定は

{
AbandonProcessGroup = 1;
Label = "com.apple.periodic-daily";
LowPriorityIO = 1;
Nice = 1;
ProgramArguments = (
"/usr/sbin/periodic",
daily
);
StartCalendarInterval = {
Hour = 3;
Minute = 15;
};
}

であるが、Mavericksでは

{
AbandonProcessGroup = 1;
Label = "com.apple.periodic-daily";
LaunchEvents = {
"com.apple.xpc.activity" = {
"com.apple.periodic-daily" = {
AllowBattery = 0;
GracePeriod = 14400;
Interval = 86400;
Priority = Maintenance;
Repeating = 1;
};
};
};

LowPriorityIO = 1;
Nice = 1;
ProgramArguments = (
"/usr/libexec/periodic-wrapper",
daily
);
}

となっている。StartCalendarIntervalがなくなり、LaunchEventsに置き換わっている。また、ProgramArgumentsが/usr/sbin/periodic dailyから/usr/libexec/periodic-wrapper dailyに変更されている。manを見るとわかるが、periodic-wrapperを直接実行することは出来ない*6。じゃあこれはなんなんだ?となるが、/usr/sbin/periodicは健在で、こちらに適切な引数を与えて実行すれば良いので、取り敢えず深く考えないことにする。

設定の変更

基本的には以前と同じにすれば良いので、実行すべきコマンドを適切に変更した上で、スケジュールをLaunchEventsではなくStartCalendarIntervalで指定すれば良い。オリジナルの設定ファイルは、拡張子をplis_として別名保存し、設定を変更してみた。以下は変更の為のコマンドである。launchctlで一度unloadして、ファイルをコピーし、設定を書き換えたのち、再びlaunchctlでloadする。
赤字で書いた部分を変更すれば、任意の日付・時刻に実行させることができる。

periodic-dailyの変更
launchctl unload -w /System/Library/LaunchDaemons/com.apple.periodic-daily.plist
cp /System/Library/LaunchDaemons/com.apple.periodic-daily.plist /System/Library/LaunchDaemons/com.apple.periodic-daily.plis_
defaults delete /System/Library/LaunchDaemons/com.apple.periodic-daily LaunchEvents
defaults write /System/Library/LaunchDaemons/com.apple.periodic-daily StartCalendarInterval -dict Hour -int 3 Minute -int 15
defaults write /System/Library/LaunchDaemons/com.apple.periodic-daily ProgramArguments -array /usr/sbin/periodic daily
launchctl load -w /System/Library/LaunchDaemons/com.apple.periodic-daily.plist

periodic-weeklyの変更
launchctl unload -w /System/Library/LaunchDaemons/com.apple.periodic-weekly.plist
cp /System/Library/LaunchDaemons/com.apple.periodic-weekly.plist /System/Library/LaunchDaemons/com.apple.periodic-weekly.plis_
defaults delete /System/Library/LaunchDaemons/com.apple.periodic-weekly LaunchEvents
defaults write /System/Library/LaunchDaemons/com.apple.periodic-weekly StartCalendarInterval -dict Hour -int 3 Minute -int 15 Weekday -int 6
defaults write /System/Library/LaunchDaemons/com.apple.periodic-weekly ProgramArguments -array /usr/sbin/periodic weekly
launchctl load -w /System/Library/LaunchDaemons/com.apple.periodic-weekly.plist

periodic-monthlyの変更
launchctl unload -w /System/Library/LaunchDaemons/com.apple.periodic-monthly.plist
cp /System/Library/LaunchDaemons/com.apple.periodic-monthly.plist /System/Library/LaunchDaemons/com.apple.periodic-monthly.plis_
defaults delete /System/Library/LaunchDaemons/com.apple.periodic-monthly LaunchEvents
defaults write /System/Library/LaunchDaemons/com.apple.periodic-monthly StartCalendarInterval -dict Day -int 1 Hour -int 5 Minute -int 30
defaults write /System/Library/LaunchDaemons/com.apple.periodic-monthly ProgramArguments -array /usr/sbin/periodic monthly
launchctl load -w /System/Library/LaunchDaemons/com.apple.periodic-monthly.plist

書き換わったかどうか確認してみよう。

for i in dai week month
do
defaults read /System/Library/LaunchDaemons/com.apple.periodic-${i}ly|less
done

もっと詳細に指定したい場合はlaunchdの時刻指定を複数時刻にしたい - 別館 子子子子子子(ねこのここねこ)を参照のこと。

*1:ファイルサーバについては実はあまりめでたくなかったが、今回は関係無い。

*2:/etc/{dai|week|month}ly.localがあると続けてそれを実行するのも同じ。

*3:1日

*4:7日

*5:約30.4日

*6:実行してみても、実行されて欲しいスクリプトが実行されない。