OSX Yosemite and the 8-year-old Bash

July 14, 2015

Over a decade ago, I traded my bag-of-hurt dualboot setup with Windows XP and Linux for something ‘better’. I got a nice 12” milk-white iBook G4 with Mac OSX 10.3. It offered me considerably lower performance than my old laptop, but that would be offset by the giant leap in productivity I expected to see from not having to deal with my previous annoyances. Annoyances like all kinds of things in Linux that didn’t work properly (Linux on the desktop was pretty crappy back in 2003), or just using Windows in general.

In short, Linux was broken all the time, and Windows didn’t offer me the tools and the workflow that I wanted. OSX fixed both. It ‘just worked’, and gave me all the tools I wanted… and twice the battery life. I just wanted a proper *NIX desktop. All the CLI tools that I need, a nice GUI, and Microsoft Office because I had to.

That ‘giant leap in productivity’ I was expecting? Totally happened.

Fast forward to 2015. I am still using Macs exclusively, even though I tried switching back to Linux a few years ago (but failed). I still feel that OSX is the best desktop OS for me. But I no longer feel that Apple is really serving the *NIX users and sysadmins the way they should. For instance, there is no proper built-in hypervisor like KVM. There is no libcontainer for native Docker support. Apple ships an old version of Vim that lacks functionality. And so on…

But while Vim is just one or two minor versions behind, Bash is about 8 years behind. Bash 4.0 was released in 2009, but Apple still ships version 3.2, which was released in 2007.

The reason for this seems to be that Apple doesn’t want to ship software that was released under the GPL v3 license. Bash 4.x uses that license, so Apple is sticking to 3.2.x. And if all you ever do on the command line is pasting commands you found on the internet, that’s basically fine.

But what if you wanted, for example, associative arrays? Zsh has had those for nearly a decade, and Bash got them in version 4. But if you’re on a Mac, then declare -A foo gives you an error. Because of licenses.

Fix all the things (and get associative arrays)

If you are even a little bit serious about using the command line in OSX, I assume you already have Homebrew installed. If not, click here right now, and get it done already.

If you have a working install of Homebrew (when in doubt, run brew doctor to check), you can install bash via Homebrew:

$ brew install bash bash-completion

We are also installing a more recent completion package to match our newer shell. Make sure to follow the instructions about updating your .bash_profile to actually use the completion stuff.

Next, let’s add our new shell to the list of white-listed shells on our Mac:

$ sudo -i
# echo "$(brew --prefix)/bin/bash" >> /etc/shells
# exit

Now let’s change our login shell to the new version of Bash:

$ chsh -s $(brew --prefix)/bin/bash

Also, make sure that /usr/local/bin and /usr/local/sbin are in your $PATH variable before the regular /usr/bin and /usr/sbin. (Assuming you have a default install of Homebrew and brew --prefix returns /usr/local.

What have I gained, exactly?

Well, for starters, you can now use associative arrays, if that’s something you like. For other new features in Bash 4, check here. But besides the new stuff in Bash 4, you have gained access to easy updates of Bash. And future versions. Because as long as Bash is using GPL v3, don’t expect Apple to ship a new version. Not unless they really, really, really have to.