Changes to macOS version comparisons in macOS Big Sur
Old and busted
Up until now, we’ve been using the “Product Version” (i.e. 10.15.7) of macOS to perform version comparisons within bash scripts. This typically involves splitting apart the product version into “Major”, “Minor” and “Patch” numbers (i.e. the minor version of macOS Catalina 10.15.7 is 15) and using these in comparison functions. This is typically obtained using the sw_vers
binary.
- For the “Major” version (i.e 10):
/usr/bin/sw_vers -productVersion | awk -F. '{print $1}'
- For the “Minor” version (i.e 15):
/usr/bin/sw_vers -productVersion | awk -F. '{print $2}'
- For the “Patch” version (i.e. 7):
/usr/bin/sw_vers -productVersion | awk -F. '{print $3}'
… with a comparison function looking something like:
if [[ $(/usr/bin/sw_vers -productVersion | awk -F. '{print $2}') -ge 15 ]]; then
echo "OS Version is 10.15 or newer, proceeding..."
else
echo "OS Version is 10.14 or older; this script will not work. Exiting..."
exit 1
fi
This has unfortunately been turned on its head with Apple’s latest operating system, macOS Big Sur, as the numbering scheme for the minor version has been reset to 0 (The current version of macOS Big Sur as of the date of this post is 11.0.1)1. This means that in order to continue using version comparisons, one must complicate the comparison with multiple conditions, for example:
if [[ $(/usr/bin/sw_vers -productVersion | awk -F. '{ print $1 }') -ge 11 ]]; then
echo "OS Version is macOS Big Sur or newer, proceeding..."
if [[ $(/usr/bin/sw_vers -productVersion | awk -F. '{ print $2 }') -ge 1 ]]; then
echo "OS Version is macOS Big Sur 11.1 or newer, proceeding..."
else
echo "OS Version is macOS Big Sur 11.0 or older; this script will not work. Exiting..."
exit 1
fi
else
echo "OS Version is macOS Catalina or older, proceeding..."
if [[ $(/usr/bin/sw_vers -productVersion | awk -F. '{ print $2 }') -ge 15 ]]; then
echo "OS Version is macOS Catalina 10.15 or newer, proceeding..."
else
echo "OS Version is macOS Mojave 10.14 or older; this script will not work. Exiting..."
exit 1
fi
fi
… adding in the comparison of patch versions to the above code only serves to further complicate matters.
New hotness
An alternative method of comparing minor and patch versions of macOS would be to use the build number in place of the product version. For example, on macOS Catalina (10.15.7):
- For the “Minor” version (i.e. 19)
/usr/bin/sw_vers -buildVersion | cut -c1-2
- For the “Patch” version (i.e. H)
/usr/bin/sw_vers -buildVersion | cut -c3
At a glance, these numbers and letters may not seem intuitive, however they track directly with the minor and patch versions in Apple’s versioning scheme, and they have done, going back as far as Mac OS X Mountain Lion (Mac OS X Lion skipped F in the patch version), for example:
MACOS PRODUCT VERSION | MACOS BUILD NUMBER |
---|---|
macOS 10.15.0 | 19A583 |
macOS 10.15.1 | 19B88 |
macOS 10.15.2 | 19C57 |
macOS 10.15.3 | 19D76 |
macOS 10.15.4 | 19E266 |
macOS 10.15.5 | 19F96 |
macOS 10.15.6 | 19G73 |
macOS 10.15.7 | 19H2 |
As you can see, 10.15 tracks to 19, and the minor version tracks to A though H, with A being 0 and H being 7.
This changes slightly with macOS Big Sur:
MACOS PRODUCT VERSION | MACOS BUILD NUMBER |
---|---|
macOS 11.0.0 | 20A2411 |
macOS 11.0.1 | 20B29 |
macOS 11.1 (beta) | 20C5048k |
Understanding this, we can then create comparisons between the minor versions, without having to “nest” comparisons. For example:
if [[ $(/usr/bin/sw_vers -buildVersion | cut -c1-2) -ge 20 ]]; then
echo "OS Version is macOS Big Sur 11.0 or newer, proceeding..."
else
echo "OS Version is macOS Catalina 10.15 or older; this script will not work. Exiting..."
exit 1
fi
Another cool thing we can do is to use string comparisons 2 to further compare minor versions without having to convert letters to numbers. For example:
if [[ $(/usr/bin/sw_vers -buildVersion | cut -c3) > A ]]; then
echo "OS Version is macOS Big Sur 11.0.1 or newer, proceeding..."
else
echo "OS Version is macOS Big Sur 11.0.0 or older; this script will not work. Exiting..."
exit 1
fi
The usage of the system version compatibility mode (export SYSTEM_VERSION_COMPAT=1
) in scripts is not explored as part of this article.
- As we are only at the beginning of the macOS Big Sur OS cycle, it remains to be seen whether Apple will continue to update patch versions as they have done every 2-3 months, with and increment to the minor version update once per year, or whether they’ll start to implement a versioning system more akin to iOS’s version structure, i.e. the next version of macOS would be 12.0. The latest macOS 11.1 beta indicates this to be true… Howard Oakley mentions this in one of his recent posts… Stay tuned. ↩︎
- The
<
and>
operators are not available insh
↩︎