Background
I was looking for time-based project similar to Outset (which runs boot and login scripts stored in various directories), and apparently there’s one already baked into macOS that will run daily, weekly, and monthly scripts.
Shoutout to @elios on the MacAdmins Slack for letting me know about periodic
Launch Daemons
If you run sudo launchctl list | grep periodic-
, you’ll see that these launch daemons are running:
com.apple.periodic-monthly
com.apple.periodic-weekly
com.apple.periodic-daily
And, though I don’t love SIP in general, it’s great for this, because you can’t actually disable the launch daemons:
sudo launchctl unload /System/Library/LaunchDaemons/com.apple.periodic-daily.plist
/System/Library/LaunchDaemons/com.apple.periodic-daily.plist: Operation not permitted while System Integrity Protection is engaged
So that means as long as you can enforce your daily, weekly, and monthly scripts being in the right place, with the right permissions, and with the right hash, they’ll be run regularly-ish.
Locations of Scripts
You can find scripts in /etc/periodic/daily
, /etc/periodic/weekly
, and /etc/periodic/monthly
. You can also put your own scripts in there (root-owned, 755 permissions), and they’ll run alongside the ones that come with macOS.
According to /etc/defaults/periodic.conf
, though, there’s another recommended place to put scripts:
# periodic script dirs
local_periodic="/usr/local/etc/periodic"
So that would be /usr/local/etc/periodic/daily
, /usr/local/etc/periodic/weekly
, and /usr/local/etc/periodic/monthly
. Having your scripts separated from the built-in scripts may be a good idea, even though they’ll run fine alongside the built-in scripts.
Logging
If your script has any echo
commands, the output will go to the appropriate log file (by default, those logs would be /var/log/daily.out
, /var/log/weekly.out
, and /var/log/monthly.out
), but there won’t necessarily (again, with the default settings) be any other indicators in the daily, weekly, and monthly logs that your scripts ran.
The format of the log seems to be a date/time, all the echo
statements from the scripts run, and then a closer like -- End of daily/weekly/monthly output --
.
Invoking manually
If you don’t want to wait until the next day, week, or month, you can do some manual testing by running a command like this, for example: sudo periodic daily
No TCC/PPPC support
Allowing full disk access to a script relies on giving that access to the actual parent process. As far as I can tell, the parent process is the /usr/sbin/periodic
binary, but that binary (although shipped with macOS) isn’t code-signed.
Leave a Reply