I'm writing a shell script that I want to be theoretically compatible with very old versions of Mac OS X (I say "theoretically", because I lack any super-old machines to actually test with). The script uses the output of ${OSTYPE:6} to determine which release of Mac OS X it's running on.

On a machine running 10.13 High Sierra, echo ${OSTYPE:6} returns 17. On a machine running 10.10 Yosemite, it returns 14. Logic thus suggests that the command would output "15" on 10.11 and "16" on 10.12.

(This is useful, because it allows me to include lines like if [[ ${OSTYPE:6} -ge 14 ]]; then DoThing; fi to run DoThing on any system running Yosemite and newer.)

Does this pattern hold for old releases as well? For example, would the command return "4" on the original 10.0?

I ask because, well, it would be odd to start at 4, so I'm worried that somewhere in history, the number was incremented by a point update.

  • 1
    For some older versions, it returns a dotted number pair. On OS X 10.6.8 I get "10.0", and on OS X 10.3.9 I get "7.0". Unfortunately, that means bash can't do numeric comparisons on it in these versions. Jun 19 '19 at 19:45
  • @GordonDavisson Ugh, thank you for the heads up! I have now made the check a much less clean if (( $(echo "${OSTYPE:6} > 13" | bc -l) )); then DoThing; fi Jun 20 '19 at 3:14

That sounds very much like it's returning the Darwin version.

Your theory works well from 10.15 Mojave [18] back to 10.2 Jaguar [6] but fails before that, as Darwin was 1.x.x at that point.

There's a full list at Wikipedia - macOS


On a machine running 10.13 High Sierra, echo ${OSTYPE:6} returns 17...

Here's an old PowerMac G5 running OS X 10.5 circa 2009:

$ bash --version
GNU bash, version 3.2.17(1)-release (powerpc-apple-darwin9.0)

$ sh --version
GNU bash, version 3.2.17(1)-release (powerpc-apple-darwin9.0)

$ echo ${OSTYPE:6}

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.5.8
BuildVersion:   9L31a

$ system_profiler SPSoftwareDataType

    System Software Overview:

      System Version: Mac OS X 10.5.8 (9L31a)
      Kernel Version: Darwin 9.8.0
      Boot Volume: Macintosh HD
      Boot Mode: Normal
      Computer Name: PowerMac
      User Name: Jeffrey (jwalton)
      Time since boot: 66 days 3:46

I've never used if [[ ${OSTYPE:6} -ge 14 ]]; then DoThing; fi. However, I've used similar to this in shell scripts and Makefiles:

IS_OLD_DARWIN=$(system_profiler SPSoftwareDataType 2>/dev/null | grep -i -c -E "OS X 10\.[0-5]")
if [[ "$IS_OLD_DARWIN" -ne 0 ]]; then DoThing; fi

I can provide remote SSH access to the PowerMac. I use it for testing open source libraries, like Crypto++ and OpenSSL. Email me at noloader, gmail account if you want access.

As far as I know, the oldest version of Bash you can get your hands on for testing is Bash 2.x circa 2004. Download Fedora 1 from /pub/archive/fedora/linux/core.

  • Thank you! I won't be taking you up on the ssh offer right now—I'm not quite dedicated enough to this project—but I really appreciate it! Jun 20 '19 at 3:15
  • General question—do you not have any security concerns about leaving an outdated OS accessible via SSH? Have you done anything special to harden the system? Jun 30 '19 at 15:03
  • 1
    @Wowfunhappy - The box is mostly safe from network attackers. The box is sitting behind my IPFire firewall. The only port accessible to the outside world is SSH. SSH is updated regularly; and I maintain Build Scripts for this scenario. The local attacker can do more damage. But folks with accounts on the box don't have to work too hard since I am happy to offer them root access if they ask for it or need it.
    – user83961
    Jun 30 '19 at 15:08

I don't have a 10.0 machine to test on, but on 10.3 and 10.5 machines, echo ${OSTYPE:6} returns a blank line ($OSTYPE on both is darwin); on 10.6, it returns 10.0.

(Incidentally, your shell script would need to explicitly invoke bash. The default shell on very old versions of OSX is tcsh, which doesn't understand the ${OSTYPE:6} syntax.)


Apple stores version information in Core Foundation and here is the source code showing how they build to each version.

I’d use sw_vers to get your version information if you’re scripting rather than use uname or other variables.

  • Would sw_vers work in a shell script? Jun 19 '19 at 17:25
  • It’s in the path of all the shipping shells on macOS / OS X / Darwin, so yes @Wowfunhappy it will work well.
    – bmike
    Jun 19 '19 at 17:27
  • Thanks. I remember why I didn't use this now—because it doesn't output an integer like OSTYPE:6, I can't use a simple -ge / -le checks to isolate "this version and everything newer/older" Jun 19 '19 at 17:31
  • @Wowfunhappy Aren’t the build numbers monotonically increasing and sortable as strings? I think there’s an entire python library / module to handle this iirc - it’s pyfacts - github.com/timsutton/python-macadmin-tools
    – bmike
    Jun 19 '19 at 17:53
  • Ah, Finlay Doobie, who fixed a bug in OS X that escaped Apple's software engineers for over a year - wired.com/2002/03/apple-ousts-coder-for-being-young
    – fd0
    Jun 19 '19 at 18:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .