Skip to content

Instantly share code, notes, and snippets.

@mattpavelle
Last active June 21, 2019 19:29
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save mattpavelle/f79f14898fe67d0a82451a02e3516de8 to your computer and use it in GitHub Desktop.
MacOS automatic scheduled updates and upgrades for Homebrew (brew) and Python (pip) - using launchd instead of cron

Cron on MacOS doesn't really work...

The launchd scripts below follow the Mac OS X way to run scripts that automatically update and upgrade brew and pip packages on a set schedule.

They will run daily as follows:

  • Homebrew (brew) Update at 3:01AM, upgrade at 3:03AM, and cleanup at 3:09AM
  • Python packages (via pip) Upgrade at 3:15AM

Installation Instructions

Logs will be stored in /private/tmp

These scripts will only run when you (the user) are logged in

  1. Copy (download then move) each plist file to ~/Library/LaunchAgents/
  2. Load each plist file one at a time via launchctl load filename where filename is name of the plist file (you can also just load them all via launchctl load com.example.*)

P.S. - if you know cron (I wish it worked on MacOS) then this is basically what we're doing:

# update brew pkgs:
1 3 * * * /usr/local/bin/brew update
3 3 * * * /usr/local/bin/brew upgrade
9 3 * * * /usr/local/bin/brew cleanup
# update python pkgs:
15 3 * * * /usr/local/bin/pip-review --auto
# update node pkgs:
20 3 * * * /usr/local/bin/npm update -g
25 3 * * * /usr/local/bin/npm prune -g
<?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.example.brew.cleanup</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/brew</string>
<string>cleanup</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>3</integer>
<key>Minute</key>
<integer>09</integer>
</dict>
<key>StandardErrorPath</key>
<string>/private/tmp/brew_cleanup.log</string>
<key>StandardOutPath</key>
<string>/private/tmp/brew_cleanup.log</string>
</dict>
</plist>
<?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.example.brew.update</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/brew</string>
<string>update</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>3</integer>
<key>Minute</key>
<integer>01</integer>
</dict>
<key>StandardErrorPath</key>
<string>/private/tmp/brew_update.log</string>
<key>StandardOutPath</key>
<string>/private/tmp/brew_update.log</string>
</dict>
</plist>
<?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.example.brew.upgrade</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/brew</string>
<string>upgrade</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>3</integer>
<key>Minute</key>
<integer>03</integer>
</dict>
<key>StandardErrorPath</key>
<string>/private/tmp/brew_upgrade.log</string>
<key>StandardOutPath</key>
<string>/private/tmp/brew_upgrade.log</string>
</dict>
</plist>
<?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>com.example.pip-review</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/bin/pip-review</string>
<string>--auto</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StartCalendarInterval</key>
<dict>
<key>Hour</key>
<integer>3</integer>
<key>Minute</key>
<integer>15</integer>
</dict>
<key>StandardErrorPath</key>
<string>/private/tmp/pip-review.log</string>
<key>StandardOutPath</key>
<string>/private/tmp/pip-review.log</string>
</dict>
</plist>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment