Every year or so Apple churns out another operating system upgrade. This has, of late, become an immutable fact of modern life. The world may be on fire and war, famine and pestilence may be actively stalking the land, but as long as Apple releases an operating system with a cutesy name some time in the fall of each year then we can rest easy in the knowledge that order is preserved, and that the Great Wheel Of The Heavens will continue to turn and drag us all along for the ride whether we like it or not.
Actually, if we’re being turn-the-chair-around-and-sit-down-to-rap-with-the-kids real, it’s not really a new operating system as much as it’s an upgrade to the existing operating system. Yes, of late they’ve incrementally increased the number associated with the thing (we’re up to macOS 12 after lingering on macOS X for nigh on a couple of decades), but the fundamentals of the thing remain essentially the same. Windows and menus and conventions like the Dock reliable persist. There’s still a mouse and folders and files and such, and there’s still a menu bar at the top of the screen.
It’s the menu bar that caught my attention this time round. Honestly, macOS 12 is pretty much the same as the old macOSes save that a) there are many, many new bells and whistles that will be widely ignored by the vast bulk of regular users, b) you can click the little “I’ve-replied-to-this-message” arrow in the built-in Mail app and it will open the relevant sent missive (finally), and c) you can now get a new menu item that you can fill full of your own little bits of code that you can write yourself without much trouble, and actually do something useful with your computer for a change.
This made me happy because I like to do a lot of useful little things with my computer and I do not have a lot of patience with trying to remember how to write code (because I am rapidly aging and don’t sleep enough or drink enough water.) When the shell of your mortal trappings is degrading by the moment you can’t be bothered to write a lot of shell scripts and so forth. A lot of new things get introduced, linger a year or two, and then disappear forever, and the risk/reward of getting intimate with things that are probably doomed tends to make me cynical.
However, this new thing is actually sort of brilliant. Apple took a long, hard look at scripting on their platforms a few years back – effectively sunsetting AppleScript and rolling a lot of that functionality into Automator on the Mac, and cooking up Shortcuts on iOS with a lot of the same DNA. iOS Shortcuts were easy to write and allowed you to do an astonishing amount of useful stuff, and now with the advent of macOS Monterey/macOS 12/what have you, they’ve brought Shortcuts to the Mac and allowed it to run shell scripts. Trust me – this is good news.
I like to block out time every week to work on my stuff. It’s an old habit, and I think it’s a good one; make sure that the software tools I use all day are patched and up-to-date, look at log files and test backups, spend a little time doing the same list of checks and maintenance that I’d do on a client machine. A bad workman blames his tools, and I like not having that excuse available. One of the things that I do as part of that is to update homebrew, and then back up my brewfile and my zsh .zprofile. These aren’t exactly the most intimidating chores, but I’ve often thought it would be nice to have a simple, one-click way to do this that wouldn’t involve manually executing a bash script or relying on launchd
or cron
to do it for me. Shortcuts for the Mac turned out to make this a terribly, terribly simple operation.
First, I needed a script to update homebrew, then go dump my brewfile to a location where it could be backed up before then copying my .zprofile to that remote location too. Said remote location is my Dropbox folder – I loathe the Dropbox app with a fiery hatred, and instead use Maestral to access Dropbox. Maestral is an open-source alternative Dropbox client that does all the things that Dropbox used to do (i.e., synchronizes your files between computers) and none of the stuff that Dropbox currently does (tries to be Google Workspace, Google Photos, some kind of terrible backup solution, treats you with a profound lack of respect, generally takes over your computer and eats all your memory and CPU). I have a Maestral folder in my home directory, which is then synchronized via Dropbox’s back end.
My work machine is a 2021 M1 MacBook Air (“Razorback” because I like The Expanse and the idea that my laptop is tiny and fast), and the behemoth I currently have toiling away in my office is a 2009 Mac Pro running Monterey via the miracle of OpenCore and SurPlus (“Rocinante”, because I like The Expanse and trend sentimental about aging machinery that can still throw down with the best of them when required). When you create a Shortcuts app on macOS and you’re signed into multiple machines with the same iCloud account then your Shortcuts get pushed to each machine – which is great, unless you want to push a file to Maestral from each machine, as then the brewfile you send from your MacBook Air will cheerfully overwrite the brewfile you’ve already pushed up from your Mac Pro. To get around this I mined ioreg
to pull out the hardware serial number from each machine, then used hostname
to grab the hostname of each machine, and finally rolled those two variables into the script so that each file that gets pushed up is labeled with the serial number and hostname of the machine that generated the file, thus:
#!/bin/zsh
# First, let's run a brew upgrade because that's just a good idea
brew upgrade
# Next, create a variable called SerialNumber that will pull the hardware serial number from ioreg
SerialNumber=$(ioreg -c "IOPlatformExpertDevice" | awk -F '"' '/IOPlatformSerialNumber/ {print $4}') ;
# ...and a variable called hName so we can grab the hostname of the machine
hName=$(hostname);
# Next we run brew bundle dump to push a brewfile to the Maestral folder
brew bundle dump --file=~/Maestral/"$SerialNumber"_"$hName"_brewfile;
# And then we'll do the same for the ZSH profile
cp ~/.zprofile ~/Maestral/"$SerialNumber"_"$hName"_zprofile
Next, open up Shortcuts (assuming you’re running macOS Monterey), which can be found in the Applications folder and which looks like this:
Open it, select “New Shortcut” from the “File” menu, then type “shell script” into the search bar and click on “Run Shell Script” from the list that auto-populates below, like so:
You can type your own shell script in there, or just copy/paste my homework in if you’d like. It’s okay. I won’t tell the teacher. Next, go to the “File” menu and choose “Preferences”, then make sure that you have “iCloud Sync” and “Allow Running Scripts” enabled (if, that is, you want to have the thing synchronize via iCloud and also, well, work.)
You might also want to tap the icon for the script at the top of the window and choose a different emoji, and to give it a pithy name. Mine’s called “Upgrade Homebrew”, because I lack imagination. Go wild, though.
Finally, close the window for your newly minted Shortcut, and you’ll find yourself back at the default “All Shortcuts” browser window. Locate your shortcut and drag it to the “Menu Bar” icon, thus:
Finally, you should be able to activate your new Shortcut by choosing it from the Shortcuts menu item that now appears on the right hand side of your macOS menu bar:
…and that’s about it.
Upgrading homebrew can – depending on how frequently you do it – take a while, and there’s no feedback from the Shortcut to let you know if it runs into an error (so it’s good to test your script out using something like CodeRunner before implementing it). The proof, however is in the pudding. And by that I mean the proof is in my Dropbox folder:
This whole exercise is just a bauble – Shortcuts is an extraordinarily powerful and incredibly flexible ecosystem for generating what promises to be a pretty amazing spectrum of solid utility applications. I think people are going to come up with some remarkable uses for it, and I can’t wait to see what they cook up…