Education

Changes to macOS version comparisons in macOS Big Sur

David Acland
11.18.2020
Share

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.

  1. 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. ↩︎
  2. The < and > operators are not available in sh ↩︎

Contact Moof IT to discuss your Mac management needs

  • logo
  • Gcloud logo

Company

Address:
1st Floor, 20 Noel street, London, W1f 8GW
Company Number: 11082827