Cron for Homebrew
Homebrew is a wonderful package manager and, for macOS users, it’s the only sensible option around. However, keeping up to date is really tedious. In this article we set a cron entry to update everything on a schedule.
I value my time.
And if you’re here, probably you value yours too. Now, brew install
always
triggers a brew update
before installing new packages anyway, so, after a
long period of time without upgrading your packages you install a new one
it can take an hour and a half of your life updating all your setup.
In this article we’ll:
- Create a script with the update commands.
- Add a new crontab entry to execute said script.
- Monitor executions.
1. Create a script with the update commands.
This is a simple task, for me the idea was to update homebrew and the gcloud
(GCP’s CLI) utility. My script looks like this:
1 2 3 4 5 6 7 8 9 10 | #!/bin/bash # script to update the system # absolute paths* HOMEBREW_BIN=/absolute/path/to/brew GCLOUD_BIN=/absolute/path/to/gcloud # update commands. $HOMEBREW_BIN update && && $HOMEBREW_BIN upgrade && $HOMEBREW_BIN cleanup; $GCLOUD_BIN components update --quiet; |
You can use the which(1)
command to figure out the absolute path for the binary
of any executable you may need to reference. Remember that the execution
environment from cron
can vary from system to system and it’s a good idea
in these scenarios to be absolutely specific.
2. Add a new crontab entry to execute said script.
Always backup cron’s data before any modification is made, you never now.
In order to access the crontab(1)
, we’ll need to edit the user’s crontab:
1 | $ crontab -e
|
Within the file, we’ll add a new entry for our script:
*/30 * * * * /path/to/your/script.sh &
If you need help setting up your cron expressions, I’d recommend you to visit the crontab.guru configurator so you can experiment and setup more complicated schedules.
3. Monitor executions
As you may already know, the way crontab(1)
works is
essentially asynchronous from your terminal. Any output produced from the
execution context can be monitored by two mechanisms:
- Use the default
crontab(1)
behavior and check themail(1)
command to get our inbox of messages from Cron. - Pipe the output into a specific logfile by using the
>
or>>
operators in bash.
Using the #2 would be the best way to do it since you will have a searchable and meaningful log. However I would advice against it in this case as the executions may be thousands per week so the file will grow in size exponentially and can cause system disruption.
Using the mail(1)
command we can monitor the execution in the
following way, this is the output of an interactive session:
❯ mail
Mail version 8.1 6/6/93. Type ? for help.
"/var/mail/humbertowoody": 1 messages 1 new
>N 1 humbertowoody@cpe-17 Tue Feb 28 16:00 21/968 "Cron <humbertowoody@cpe-172-100-67-24> source /Users/humbertowoody/tools/update-macos"
? 1
Message 1:
From humbertowoody@cpe-172-100-67-24.twcny.res.rr.com Tue Feb 28 16:00:44 2023
X-Original-To: humbertowoody
Delivered-To: humbertowoody@cpe-172-100-67-24.twcny.res.rr.com
From: humbertowoody@cpe-172-100-67-24.twcny.res.rr.com (Cron Daemon)
To: humbertowoody@cpe-172-100-67-24.twcny.res.rr.com
Subject: Cron <humbertowoody@cpe-172-100-67-24> source /Users/humbertowoody/tools/update-macos.sh && update_macos &
X-Cron-Env: <SHELL=/bin/zsh>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=humbertowoody>
X-Cron-Env: <USER=humbertowoody>
Date: Tue, 28 Feb 2023 16:00:11 -0600 (CST)
Already up-to-date.
Beginning update. This process may take several minutes.
All components are up to date.
? q
(end of session)
Here Cron will send an email with each execution so we can monitor it by using
the mail
command.
That’s it!
This script has helped me generate a better experience out of Homebrew in my local machine. I hope it helps you on your developer workflow.