Getting the Version

You can add the -productVersion argument to get just the product version number:

$ sw_vers -productVersion
10.13.1

The first part of the version number (“major” version) is always 10 (so far). The second part (“minor” version) denotes the version of macOS (11: El Capitan, 12: Sierra, 13: High Sierra, etc.) and the third (“patch” or update version) the update number. (Useful list of macOS versions and names on Wikipedia.)

Note: because the first part of the version for macOS is always10, some call the second number the major version of macOS and the third the minor version. It does not really matter as long as you are explicit what you mean and remain consistent. Documentation in code helps avoid confusion.

You can test for a specific version with string comparison:

if [[ $(sw_vers -productName) == "10.12.6" ]]; then
echo "Sierra"
fi

This will get tedious when you need to check for many patch versions. The [[ operator let’s you use the asterisk * as a wildcard in string comparisons:

The read command splits the string into a bash array with the periods as a separator. There is a lot going in this command, so let’s have a look at the pieces.

First we assign the ‘.’ to the IFS environment variable. Characters in the IFS (“Internal Field Separator”) variable are used by bash to split strings into their pieces. The normal IFS variable consists of the whitespace characters: space, tab and newline. However, we want to change this so that the read command splits at the periods in our version string. This syntax with the variable assignment directly followed by the command without a separator tells bash to change the IFS variable just for the next command. This way the standard IFS variable is not affected.

The read command splits the input into an array and assigns it to the ver variable. Then we can get the elements in the ver array using the ${ver[index]} notation. (bash arrays are zero-indexed, so the first element ${ver[0]} will always be 10.

Once you have split out the parts of the version string, you can then use them for numerical comparisons:

Get the macOS version from other Volumes

The sw_vers command only show the version for the currently booted system. System administrators often need to know the version of the OS installed on a different volume. Usually this happens in the context of installations. In installation scripts the installer system will pass the path to the target volume as the third argument $3.

On macOS the system version information is also stored in a property list file in /System/Library/CoreServices/SystemVersion.plist. In an installation script (postinstall or preinstall you can get the target system with:

Build Number

Note: update this section, because I got few things wrong. Thanks to the participants of this Slack discussion.

Aside from the numerical version number or product version, macOS also has a build number, which follows a different schema. The first part is a number which matches the “Darwin version” of macOS. Mac OS X 10.0 had a Darwin version of 4 and that number has increased with every version of Mac OS X. Currently, macOS High Sierra 10.13 has a Darwin version of 17. Then follows a single capital letter, with A being the first release of a version (i.e the 10.x.0 version), B is the first patch update (10.x.1) and so on.).

Finally the last number is the build number. The build number usually incremented during Apple internal development. You can see the build number increasing during beta releases.

However, sometimes Apple will release hardware specific versions of macOS which usually have four digit build numbers (usually starting with a 2). Also security updates and other “unexpected updates” can change the build number (usually to four digits starting with a 1) without changing the numerical version number.

Sometimes there might be an a appended to the build number. This means that there was an update to the installer, but not the code inside the installer. This frequently (but not exclusively) happens during the beta phase.

Thanks to Elliot Jordan we have a great info graphic!

Made up a little graphic to explain macOS versions, in case it’s useful. You can programmatically compare if you split the string right. pic.twitter.com/tBhhwwt15n

Because of this it can also be useful to parse the build number out of the build version. Since the first two parts of the build version are directly mapped to the numerical version, we are only interested in the number: