Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Upcoming MacOS Catalina to Ditch Bash in Favour of Zsh

Upcoming MacOS Catalina to Ditch Bash in Favour of Zsh

This item in japanese

At WWDC 2019, its official developer conference, Apple announced a number of new products, including the upcoming version of its desktop OS, dubbed macOS Catalina, which is going to replace the default command line shell bash with zsh for all newly created accounts.

Apple did not provide any rationale for their decision. Bash is a hugely popular Unix shell that has been distributed as the default login shell in most Linux distributions and macOS versions, up to now at least. In fact, the stable version of macOS at the time of this writing, macOS 10.14.5, includes bash 3.2.57, which was released in 2007. So, it seems that while bash has kept evolving through the years, reaching version 5.0 at the beginning of 2019, it has remained in a kind of frozen state on macOS for the last 10+ years.

There are a number of reasons why this is not desirable at all. On the one hand, sticking to version 3.2, you do not get all the bug fixes and enhancements that made it into bash through versions 4 and 5. Namely, bash 4 included support for associative arrays, programmable autocompletion, a new ** glob operator, and various syntactic shortcuts. On the same line, bash 5 introduced a few new environment variables, improved history management, and local variable value inheritance across scopes. On the other hand, one major issue with running such old software is security. Most notoriously, bash was shown vulnerable to remote code execution a few years ago, when researchers leveraged a bash feature, i.e., the possibility of defining functions in environment variables to craft a successful remote attack. Apple promptly released a patch for its operating systems at that time, along with other OS maintainers, but it is still not clear what the security implications of running a 10+ year old program can be, especially in networked environments. Luckily, the option to upgrade bash to its latest version has always been available on macOS, thanks to package management tools such as MacPorts and Homebrew, let alone the possibility of manually building it from the official distribution.

So, the decision to replace bash 3.2 with something newer was surely a good one. The only question would be why Apple chose to switch to zsh instead of bash 5. Here, we can only speculate, as several people do, that this decision comes down to the licensing model of bash. Simply stated, bash adopted GPL 3 starting with its version 4, while zsh adopts the more permissive MIT license. This hypothesis would also explain why macOS got stuck with bash 3.2. As a matter of fact, Apple does not include any GPL 3-licensed software in macOS and has been known to be steadily freeing up their desktop OS from GPL-licensed software. This kind of policies fit well in a business landscape that has been fighting the GPL 3 due to its no-tivoization clauses and with the general trend away from GPL and towards more permissive licenses that was fueled by many business companies when they started to significantly contribute to open source software a number of years ago.

From a user perspective, deriving both from the Bourne shell, zsh and bash are not dissimilar, yet many incompatibilities do exist. Those incompatibilities are not going to affect the scripts you run as executable, since they will be run under the shell they specify using the shebang, e.g., #!/bin/bash or the more correct #!/usr/bin/env bash. But there will surely be issues when trying to source a bash script into zsh, e.g. . ./, or if you explicitly attempt to run it through zsh, e.g., zsh Most significant, anyway, will be the effort required to port your .bashrc environment to .zshrc, especially for prompt settings, completion functions and shell options.

It is possible, of course, to change the default login shell for any existing macOS user account by going to System Preferences > Users & Groups, then ctrl-clicking on your user and selecting Advanced options. Alternatively, you can run the command csh -s /bin/zsh, giving any shell path listed under /etc/shells.

Rate this Article