I’ve been updating an installer
bash script that needs to install different files depending on the version of Mac OS X (and Darwin, for that matter) that the machine is running and so set out to find the easiest, most straightforward way to check the OS version.
Of course, the
hostinfo command shows you most of the juicy details one would need, but it’s not worth trying to parse it.
sysctl lets you query various kernel states, including the OS release version:
sysctl -n kern.osrelease
Which will spit back something like the following (on Mac OS X 10.5.4, in this example):
This is the Darwin release number. To convert a darwin release version number to a Mac OS X version number just subtract 4 from the major revision (9, in this case) and then prepend the ’10.’ to the entire thing. So, 9.4.0 becomes 10.5.4.0.
You can also use
uname -r to get the OS release version, but I’m going to stick with
sysctl for now.
Of course, you can’t do a direct comparison, so you’ll want to compare either the major or the minor revision (the last release field is always zero, so it can be ignored). The easiest way to do that is to pipe the output from
sysctl through the
The following will give you the major release number (again, 9, in this case):
sysctl -n kern.osrelease | cut -d . -f 1
It cuts the output of
sysctl on the ‘.’ delimiter and returns the first field. We can return the second field (the minor revision; 4, in our example) like so:
sysctl -n kern.osrelease | cut -d . -f 2
In my script, I simply needed to test if the machine was running Tiger or earlier, or Leopard or newer. Here’s a quick example of getting that functionality:
#!/bin/bash if [ `sysctl -n kern.osrelease | cut -d . -f 1` -lt 9 ]; then echo "Tiger or earlier" else echo "Leopard or newer" fi
If you’re doing something more advanced, it might be easier to set variables first:
darwinos_major=`sysctl -n kern.osrelease | cut -d . -f 1` darwinos_minor=`sysctl -n kern.osrelease | cut -d . -f 2`
Then just reference
$darwinos_minor whenever needed.