How my LaunchD demon was setup
I switched to crontab now, and it seems to work much better, but before I was trying to run periodic job with this daemon setup.
From first-time-setup
script
HOME="${HOME:=/Users/max}"
LIBRARY=$HOME/Library
LOGS="$LIBRARY/Logs"
# How my LaunchD demon was setup
echo "* symlinking launch agent for hourly job"
mkdir -p $LIBRARY/LaunchAgents
mkdir -p $LOGS/HourlyJob
ln -nsf "$CLOUD_CONFIGS"/LaunchAgents/* "$LIBRARY/LaunchAgents"
if launchctl list com.max.hourly &>/dev/null; then
echo " * hourly job daemon is already loaded (skipping)"
else
echo " * loading hourly job daemon"
launchctl load -w "$LIBRARY/LaunchAgents/com.max.hourly.plist"
fi
Separate hourly-reload
script
#!/usr/bin/env bash
launchctl unload -wF /Users/max/Library/LaunchAgents/com.max.hourly.plist && \
launchctl load -wF /Users/max/Library/LaunchAgents/com.max.hourly.plist
App folder hierarchy (in the Configurations dir) HourlyJob.app/Contents/MacOS/HourlyJob
<- this is the bash script
(I added this app to Security & Privacy -> Full Disk Access right from this path.)
The LaunchAgent config in the LaunchAgents/com.max.hourly.plist (in the Configurations dir)
<?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.max.hourly</string>
<key>ProgramArguments</key>
<array>
<string>/Users/max/Documents/Configurations/HourlyJob.app/Contents/MacOS/HourlyJob</string>
</array>
<key>Nice</key>
<integer>1</integer>
<key>StartInterval</key>
<integer>3600</integer>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/Users/max/Library/Logs/HourlyJob/HourlyJob-stderr.log</string>
<key>StandardOutPath</key>
<string>/Users/max/Library/Logs/HourlyJob/HourlyJob-stdout.log</string>
</dict>
</plist>
Code snippets in this post are covered by 0BSD License.