darelon
05-05-2005, 08:07 AM
[Not completely sure which forum this should be in—apologies to the moderators if this is the wrong one…]
In Mac OS X.4, Apple moved the scheduling of the daily, weekly and monthly maintenance jobs from cron to the shiny new launchd system, as can be seen from /etc/crontab:# The periodic and atrun jobs have moved to launchd jobs
# See /System/Library/LaunchDaemons
#
# minute hour mday month wday who command
Unfortunately, these jobs are still running on a fixed schedule in the middle of the night as before. Many computers will usually be shutdown at that time, resulting in the periodic jobs to be skipped most or all of the time.
For those users who previously used e.g. anacron to make sure any overdue periodic jobs were run after starting or waking the system: below are a Perl script and a launchd job specification that may be used instead.
The Perl script:
#!/usr/bin/perl
#
# kick_periodic_jobs
#
# Kick off overdue daily, weekly or monthly periodic jobs
#
use Time::gmtime;
use File::stat;
$daily_logfile = "/var/log/daily.out";
$weekly_logfile = "/var/log/weekly.out";
$monthly_logfile = "/var/log/monthly.out";
# Check daily periodic job
$daily_log_age = -M $daily_logfile;
$daily_log_age = 1 if not defined $daily_log_age;
system("periodic daily") if $daily_log_age >= 1;
# Check weekly periodic job
$weekly_log_age = -M $weekly_logfile;
$weekly_log_age = 7 if not defined $weekly_log_age;
system("periodic weekly") if $weekly_log_age >= 7;
# Check monthly periodic job
$current_year = gmtime()->year;
$current_mon = gmtime()->mon;
$current_mday = gmtime()->mday;
if (-e $monthly_logfile) {
$monthly_log_year = gmtime(stat($monthly_logfile)->mtime)->year;
$monthly_log_mon = gmtime(stat($monthly_logfile)->mtime)->mon;
$monthly_log_mday = gmtime(stat($monthly_logfile)->mtime)->mday;
}
else {
$monthly_log_year = 1;
$monthly_log_mon = 1;
$monthly_log_mday = 1;
}
system("periodic monthly") if $monthly_year < $current_year && $monthly_log_mon < $current_mon && $monthly_log_mday <= $current_mday;
#EOF
You can install above script anywhere you want—I used /usr/local/bin/kick_periodic_jobs. Remember to make it executable; probably best to change the owner/group to root/wheel and set rwxr--r-- permissions.
If you save it elsewhere, also make sure to enter the correct path to the script in the ProgramArguments key in the launchd job specification.
The launchd job specification should be saved in /Library/LaunchDaemons as e.g. local.periodic.kick.plist, with owner/group set to root/wheel and rw-r--r-- as permissions:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>local.periodic.kick</string>
<key>UserName</key>
<string>root</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/kick_periodic_jobs</string>
</array>
<key>StartInterval</key>
<integer>600</integer>
</dict>
</plist>
To add this to the list of jobs known by launchd:
$ sudo launchctl load <path of job plist file>
You can check the list of loaded jobs with:
$ sudo launchctl list
Hope this may be of use to some, at least as a sketch of integrating a small piece of 'old' functionality with the new launchd system.
Ciao,
Roeland.
In Mac OS X.4, Apple moved the scheduling of the daily, weekly and monthly maintenance jobs from cron to the shiny new launchd system, as can be seen from /etc/crontab:# The periodic and atrun jobs have moved to launchd jobs
# See /System/Library/LaunchDaemons
#
# minute hour mday month wday who command
Unfortunately, these jobs are still running on a fixed schedule in the middle of the night as before. Many computers will usually be shutdown at that time, resulting in the periodic jobs to be skipped most or all of the time.
For those users who previously used e.g. anacron to make sure any overdue periodic jobs were run after starting or waking the system: below are a Perl script and a launchd job specification that may be used instead.
The Perl script:
#!/usr/bin/perl
#
# kick_periodic_jobs
#
# Kick off overdue daily, weekly or monthly periodic jobs
#
use Time::gmtime;
use File::stat;
$daily_logfile = "/var/log/daily.out";
$weekly_logfile = "/var/log/weekly.out";
$monthly_logfile = "/var/log/monthly.out";
# Check daily periodic job
$daily_log_age = -M $daily_logfile;
$daily_log_age = 1 if not defined $daily_log_age;
system("periodic daily") if $daily_log_age >= 1;
# Check weekly periodic job
$weekly_log_age = -M $weekly_logfile;
$weekly_log_age = 7 if not defined $weekly_log_age;
system("periodic weekly") if $weekly_log_age >= 7;
# Check monthly periodic job
$current_year = gmtime()->year;
$current_mon = gmtime()->mon;
$current_mday = gmtime()->mday;
if (-e $monthly_logfile) {
$monthly_log_year = gmtime(stat($monthly_logfile)->mtime)->year;
$monthly_log_mon = gmtime(stat($monthly_logfile)->mtime)->mon;
$monthly_log_mday = gmtime(stat($monthly_logfile)->mtime)->mday;
}
else {
$monthly_log_year = 1;
$monthly_log_mon = 1;
$monthly_log_mday = 1;
}
system("periodic monthly") if $monthly_year < $current_year && $monthly_log_mon < $current_mon && $monthly_log_mday <= $current_mday;
#EOF
You can install above script anywhere you want—I used /usr/local/bin/kick_periodic_jobs. Remember to make it executable; probably best to change the owner/group to root/wheel and set rwxr--r-- permissions.
If you save it elsewhere, also make sure to enter the correct path to the script in the ProgramArguments key in the launchd job specification.
The launchd job specification should be saved in /Library/LaunchDaemons as e.g. local.periodic.kick.plist, with owner/group set to root/wheel and rw-r--r-- as permissions:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>local.periodic.kick</string>
<key>UserName</key>
<string>root</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/kick_periodic_jobs</string>
</array>
<key>StartInterval</key>
<integer>600</integer>
</dict>
</plist>
To add this to the list of jobs known by launchd:
$ sudo launchctl load <path of job plist file>
You can check the list of loaded jobs with:
$ sudo launchctl list
Hope this may be of use to some, at least as a sketch of integrating a small piece of 'old' functionality with the new launchd system.
Ciao,
Roeland.