Date Created: 2024-12-31
By: 16BitMiker
[ BACK.. ]
Maintaining a Mac remotely can be challenging, especially when you're juggling updates, security patches, and package management over SSH. To streamline this process, I put together a script that handles most of the routine maintenance tasks I’d normally do in person. It’s designed to be reliable, informative, and safe enough for unattended updates—especially helpful when you're managing systems from a distance.
The script outlined below is a Bash-based automation tool that:
Verifies dependencies like Homebrew and mas
Ensures the correct permissions on Homebrew’s Perl installation
Executes updates across Homebrew, the Mac App Store, and system software
Uses a Perl wrapper to print color-coded, readable output with useful feedback
Let’s break it down.
x
# Set strict error handling to catch issues early
set -euxo pipefail
# ✅ Check for Homebrew installation
command -v brew >/dev/null 2>&1 || {
echo "Error: Homebrew is not installed. Please install Homebrew first."
exit 1
}
# ✅ Fix ownership and permissions for Perl in Homebrew
# This helps avoid permission errors when upgrading or reinstalling Perl modules
sudo chown -R $(whoami) /opt/homebrew/Cellar/perl
sudo chmod -R u+rwX /opt/homebrew/Cellar/perl
# ✅ Perl wrapper to execute and format commands
perl -MTerm::ANSIColor=':constants' -nlE '
# Skip blank lines and comments
next if m~^$|^\#~;
# Print the command being run in green
say q|> |, GREEN $_, RESET "";
# Run the command via system()
system $_;
# If the command failed, print a warning in red
if ($? != 0)
{
warn q|> |, RED qq|Failure Detected: |, RESET qq|$!\n|;
}
# At the end, show a success message
END
{
say q|> |, GREEN q|All Done! Bye bye :)|, RESET "";
}
' << EOF
# 🧰 Homebrew maintenance
brew update -q
brew upgrade -q
brew upgrade --cask -q
brew cleanup -q
brew autoremove -q
brew doctor -q
brew missing -q
# 🛍️ Mac App Store updates
mas upgrade -q
# 🔒 System security updates
softwareupdate --install --recommended
# 🧑•💻 Developer tools update (no error if already installed)
xcode-select --install 2>/dev/null || true
EOF
xxxxxxxxxx
set -euxo pipefail
This combination of flags ensures your script behaves predictably:
-e
: Exit immediately on error
-u
: Treat unset variables as errors
-x
: Print each executed command (useful for debugging)
pipefail
: Prevents silent failures in command pipelines
This setup is especially important when working remotely. You want the script to stop the moment something goes wrong—so you’re not left wondering what happened hours later.
xxxxxxxxxx
command -v brew >/dev/null 2>&1
This line checks if Homebrew is available in the system’s executable path. If not, the script halts gracefully with a clear message. No ambiguous errors later—just a clear signal to install the missing tool first.
xxxxxxxxxx
sudo chown -R $(whoami) /opt/homebrew/Cellar/perl
sudo chmod -R u+rwX /opt/homebrew/Cellar/perl
If you’ve ever run into inexplicable errors upgrading Perl modules via Homebrew, chances are it’s a permissions issue. These two lines:
Change ownership of the Perl Cellar to the current user
Grant read/write access and directory-only execute permission using u+rwX
The capital X
is a smart move—it only applies execute permission to directories (and existing executable files), avoiding unnecessary changes to scripts or libraries.
Why use Perl here? It provides:
Clean looped execution of each command
Colorized output using Term::ANSIColor
Easy filtering of comments and blank lines
Simple error reporting based on return codes ($?
)
Each command in the here-document (<< EOF ... EOF
) is processed line-by-line:
Commands are shown in green before execution
If a command fails, an error message appears in red
On successful completion, a friendly "All Done!" message appears
This makes remote logs or terminal sessions much easier to parse at a glance.
The script updates in this order:
🧰 Homebrew packages
brew update
: Refreshes the package metadata
brew upgrade
: Updates CLI tools
brew upgrade --cask
: Updates GUI apps
brew cleanup
: Removes outdated versions
brew autoremove
: Cleans up unnecessary dependencies
brew doctor
: Checks for potential issues
brew missing
: Finds broken or missing dependencies
🛍️ Mac App Store apps
mas upgrade
: Updates apps installed via the Mac App Store
🔒 macOS system updates
softwareupdate --install --recommended
: Applies Apple’s recommended updates only (avoids betas)
🧑💻 Xcode command line tools
xcode-select --install 2>/dev/null || true
: Attempts to install if not already present. The || true
avoids breaking the script if it’s already installed.
This script is perfect for:
Remote developers who SSH into their Mac
Automated maintenance setups (e.g., cron
or launchd
)
Anyone who prefers a repeatable, readable update process
Before adding it to an automated job scheduler, test it interactively to ensure it behaves as expected in your environment.
Remote system maintenance doesn’t have to be tedious or risky. With a little scripting and thoughtful use of tools like Homebrew, mas
, and Perl, you can keep your Mac healthy and up-to-date—even if it's miles away.
If you're managing multiple Macs remotely, consider expanding this into a more robust toolkit with logging, email notifications, or even Slack alerts.
Happy hacking! 🖥️📡