Fork me on GitHub

Project Notes

#271 on macOS

Using latest bash releases on the latest versions of macOS.

Notes

Since Catalina (10.15), macOS has used zsh as the default shell.

Apple still does ship bash with macOS but it is very old (v3). It can do this because it is still licensed under GPLv2, whereas the current v5 bash is under the GPLv3 license.

Bash as installed by Apple:

% bash --version
GNU bash, version 3.2.57(1)-release (arm64-apple-darwin23)
Copyright (C) 2007 Free Software Foundation, Inc.
% which bash
/bin/bash

Installing Bash with Homebrew

The latest bash shell can be installed from source, or perhaps more conveniently using the Homebrew bash formula:

% brew install bash

After installation, we have the latest bash installed:

% bash --version
GNU bash, version 5.2.21(1)-release (aarch64-apple-darwin23.0.0)
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
% which bash
/opt/homebrew/bin/bash

Adding bash to /etc/shells

The /etc/shells file contains a list of login shells on the system. Applications use this file to determine whether a shell is valid.

Adding the homebrew bash link makes it a valid option:

% cat /etc/shells
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
/opt/homebrew/bin/bash

Changing the Terminal Default

Default shell can be set for the Terminal application in General Options:

terminal_options

While this has the effect of changing the default shell used by Terminal, it does not change the default login shell (over ssh for example) or the default shell used by scripts:

$ echo $BASH_VERSION
5.2.21(1)-release
$ ./bash_version.sh 
Which version of bash am I running?
Answer: 3.2.57(1)-release

Changing the default login shell

To make a more permanent change to the login shell, the chsh utility can be used to change the default login shell for a user.

Prior to making any change:

$ echo $SHELL
/bin/zsh

Change to bash:

chsh -s /opt/homebrew/bin/bash

Open a new terminal window:

$ echo $SHELL
/opt/homebrew/bin/bash

Script Defaults

Bash scripts will conventionally specify the required shell as #!/bin/bash. Because we haven’t changed /bin/bash yet, we still get the older version in scripts:

% ./bash_version.sh
Which version of bash am I running?
Answer: 3.2.57(1)-release

What we really want is for /bin/bash to invoke the v5 version. The default /bin/bash is actually the v3 binary:

$ ls -al /bin/bash
-r-xr-xr-x  1 root  wheel  1310224 Dec 15 22:43 /bin/bash

Unfortunately, in macOS the /bin folder is read-only, even for root. So it is not possible to change this bash version.

If the bash version is significant, the best solution is to change the shebang line from #!/bin/bash to #!/usr/bin/env bash and ensure that the v5 shell is found first in the PATH:

export PATH=/opt/homebrew/bin:$PATH

Now scripts will pickup the v5 shell instead:

$ ./bash_version.sh 
Which version of bash am I running?
Answer: 5.2.21(1)-release

Credits and References

About LCK#271 bash
Project Source on GitHub Return to the Project Catalog

LittleCodingKata is my collection of programming exercises, research and code toys broadly spanning things that relate to programming and software development (languages, frameworks and tools).

These range from the trivial to the complex and serious. Many are inspired by existing work and I'll note credits and references where applicable. The focus is quite scattered, as I variously work on things new and important in the moment, or go back to revisit things from the past.

This is primarily a personal collection for my own edification and learning, but anyone who stumbles by is welcome to borrow, steal or reference the work here. And if you spot errors or issues I'd really appreciate some feedback - create an issue, send me an email or even send a pull-request.

LittleArduinoProjects LittleModelArt More on my blog