Update (26 July 2020)
Howard Oakley has reported that Big Sur is both 10.16 and 11.0.
For the purposes of shells scripts, sw_vers
will return 11.0
unless SYSTEM_VERSION_COMPAT=1
is set. If it is set, then sw_vers
will return 10.16
.
To my mind, this new information only makes the following suggestion more useful, because it will work under either scenario.
end of update
Original Post
I have already run into an issue where I’ve had to adapt some of my scripts for Big Sur.
(n.b. if you have used the -p
arg to shasum
in the past, it no longer exists in Big Sur. There is a new -U
option which is not the same as what -p
used to do. Ironically, -p
was for ‘portable’ mode.)
It has already been noted that Apple is referring to Big Sur as “macOS 11” which presumably means that sw_vers -productVersion
will return ‘11.0’ once Big Sur is out of beta.
However, at least as of this writing (10 July 2020), sw_vers -productVersion
on Big Sur returns ‘10.16’.
If you are trying to write a shell script which can be used on both Big Sur and earlier versions of macOS, how can you check to see which version you are running?
I would like to recommend the following, which uses a feature which I believe is unique to zsh
— and since Apple has made zsh
it’s preferred shell, I recommend writing all of your shell scripts in zsh
(however I should note that I may be a little biased, as I’ve been using zsh
for 20+ years).
is-at-least
The zsh
feature in question is called is-at-least
and you use it like this:
autoload is-at-least is-at-least "$MINIMUM" "$ACTUAL"
where $MINIMUM
and $ACTUAL
represent the two numbers that you want to compare. What is especially nice about is-at-least
is that it can compare version numbers such as 10.15.5 and 10.13.4 and 10.16 (or 11.0).
Note: the autoload is-at-least
line needs to be called once-per-script before you use is-at-least
but once you’ve loaded it, you can use is-at-least
as many times as you want in that script.
The key here is that regardless of whether Big Sur reports itself as 10.16 or 11.0, we can use ‘10.16’ as $MINIMUM
and then set $ACTUAL
to the version of macOS that we are using.
Note that you don’t have to use variables here, you could do this:
autoload is-at-least is-at-least "10.16" "$ACTUAL"
The result of is-at-least
will be zero if $ACTUAL
is at least equal to 10.16, or 1
if it is not.
Here’s a complete example script as a gist for those who may find it useful.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/zsh -f | |
# Purpose: Check to see if we are running on Big Sur | |
# | |
# From: Timothy J. Luoma | |
# Mail: luomat at gmail dot com | |
# Date: 2020-07-10 | |
PATH="/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin" | |
# this will check to make sure `sw_vers` exists | |
# if it does not, this is probably not macOS | |
if ((! $+commands[sw_vers] )) | |
then | |
echo "$NAME: 'sw_vers' is required but not found in $PATH" >>/dev/stderr | |
exit 2 | |
fi | |
## First we get the value for this Mac and save it to `$ACTUAL` | |
ACTUAL=$(sw_vers -productVersion) | |
## load 'is-at-least' so we can use it | |
autoload is-at-least | |
## "Is the version of macOS that we are using _at least_ 10.16?" | |
is-at-least "10.16" "$ACTUAL" | |
## EXIT will be '0' if ACTUAL is at least 10.16 | |
## EXIT will be '1' if ACTUAL is _less than_ 10.16 | |
EXIT="$?" | |
if [[ "$EXIT" == "0" ]] | |
then | |
# This is Big Sur (or later) | |
echo "YES" | |
elif [[ "$EXIT" == "1" ]] | |
then | |
# This is BEFORE Big Sur | |
echo "NO" | |
else | |
# we should never get here | |
echo "This should not have happened. EXIT = $EXIT" | |
fi | |
exit 0 |