- Joined
- Jul 17, 2019
- Messages
- 123
- Motherboard
- Asus TUF Gaming Z590-PLUS WIFI
- CPU
- i9-10900K
- Graphics
- RX 6800 XT
- Mac
- Mobile Phone
With the release of Catalina, Apple has officially changed the default shell to zsh. This will have many advantages, as the included version of bash in macOS is very old; however, zsh is technically not fully POSIX compliant, and there exist a number of great scripts that simply do not work correctly on zsh. Fortunately, getting bash back is very easy. One of the requirements I had when doing this myself was to have no dependence on brew, or MacPorts, as these leave a noticeable footprint. In the case of MacPorts, it will build everything against its on dependencies; often resulting in the duplication, or even triplication of common runtimes, libraries, etc. As such, both methods detailed in this post will not require the installation of a third party package manager.
Method #1 - reverting to classic bash
The version of bash that we've come to expect in macOS hasn't gone anywhere; however, it is technically deprecated. If you're looking to revert to something that you're used to from Mojave, High Sierra, or other previous versions of macOS, this is the choice for you. To do this, follow the steps listed below
- Open System Preferences and select Users & Groups
- Click the padlock icon to unlock these preferences, as this is required to change the relevant settings.
- Right click on your users account in the left column and click Advanced Options...
- You should see a series of options; some of which include setting the location of your home directory, changing your name, etc. Among these options look for "Login shell", and from the dropdown menu, select /bin/bash.
- Apply the changes, logout, and log back in for said changes to take affect.
Bash:
$ chsh -s /bin/bash
After entering your password, the default shell for your account will be changed. Of course, you'll need to logout and back in for this change to take affect.
Please be aware that support for anything deprecated is non existent. If there is a bug in bash, it is unlikely that Apple will ever fix it. The same is also true for security vulnerabilities; so, use this version at your own risk!
Method #2: building the latest version of bash from source
This is the preferred way to do this, as the latest version of bash will bring all the improvements that have been made since 2007, as well as bug fixes, and most importantly, security patches. This post assumes little to no experience with building from source, and as such, I will include some extra detail. Before we can begin, make sure that you have installed the Xcode command line tools. To do this, open terminal, and issue the command
Bash:
$ xcode-select --install
11/23/2020 IMPORTANT: BUILD ERROS ON 10.15.x - PLEASE READ!
So, for some reason, bash 5 will not compile against the newer xCode 12 command line tools, and as such we need to download the last set of tools for xCode 11. You can download the tools, directly from Apple, simply by clicking here. You must sign in with your AppleID and accept the developer terms of service before you can access any of the provided resources. This does not obligate you to pay for a developer account; instead, it serves as a launching point for getting started with development within the Apple ecosystem. I'm not sure when this issue will be resolved; however, please keep in mind that bash 5.1 will likely be released very soon, as we have already seen 3 different release candidates.
This does not require the entire Xcode app and takes up much less space. Depending on your hardware, and internet connection, installation time will vary, but in my experience, it doesn't take too long. Next, download the latest version of the bash source. In this post, I will be linking GNU's ftp server; however, you may see better results using a mirror that is geographically closer to your location. This post will focus on bash 5.0 since it is currently the latest release. As of bash 5.0.18, autoconf is also a requirement and bash will fail to build if it is not present; so, we will need to download the latest version of autoconf as well. While you can download the archives from a web browser, you should become familiar with using the command line, as from this point onward, we'll be working in the terminal almost exclusively. Use the following commands to download each archive. While lumping them into a single command is definitely possible, I am going to keep them separated for the sake of consistency.
Bash:
$ curl https://ftp.gnu.org/gnu/bash/bash-5.0.tar.gz -O
Bash:
$ curl https://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.xz -O
Bash:
$ tar xvf autoconf-2.69.tar.xz && cd autoconf-2.69
Bash:
$ tar xjf bash-5.0.tar.gz && cd bash-5.0
Bash:
$ ./configure --prefix=/Users/$USER/opt
Bash:
$ make -j 6
Bash:
$ make install
Bash:
$ cd ..
Bash:
$ mkdir patches && cd patches
Bash:
$ curl 'https://ftp.gnu.org/gnu/bash/bash-5.0-patches/bash50-[001-0118]' -O
Bash:
$ cd ..
$ patch -p0 -i patches/bash50-001
$ patch -p0 -i patches/bash50-002
$ patch -p0 -i patches/bash50-003
...
While there exists a command that will attempt to apply all patches at once, it may require some additional steps, and will not be covered here. Now that all patches have been applied, it's time to compile the source into binaries. We first need to make sure that the folder where the compiled autoconf binaries were installed is present in our $PATH. Think of this variable as a list of places in which bash, or other common shells will attempt to look for programs, libraries, headers, dependencies, etc. Like how we read English, this variable is parsed from left to right; that is, directories listed on the left will be checked first, and those closer to the right will be checked last. To add our previously built autoconf, we can do so with the following command.
Bash:
$ PATH=/Users/$USER/opt/bin:$PATH
Bash:
$ ./configure
$ make -j 6
Like before, make sure you specify the appropriate number of cores/threads for compilation. Of course, there is no rule that says you must use every core that you have. If there is other work which you need to keep working on, you of course may wish to specify fewer cores.
Assuming there are no errors, you should now have the bash binaries ready to be installed. Because we are cautious, we are going to check our compiled binaries for issues before installing.
Bash:
$ make check
$ sudo make install
NOTE: If you're fine with living life on the edge, you can skip make check, and go straight to install. Once finished, you should now have an up-to-date version of bash located in /usr/local/bin that should work as expected.
Code:
$ /usr/local/bin/bash --version
#expected output
GNU bash, version 5.0.16(1)-release (x86_64-apple-darwin19.4.0)
Copyright (C) 2019 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.
There's still one final step that needs to be done before we can use the previously mentioned "chsh" command to set this new version of bash as our default login shell. In the /etc directory, you'll find a file called shells that contains the locations of all valid unix shells on your system. The installation script does not automatically add your new version of bash to this file, and therefor, we need to add it ourselves.
Bash:
sudo nano /etc/shells
The file should look something like the following; you'll notice that I went ahead, and added /usr/local/bin to the end of the file.
Code:
# 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
/usr/local/bin/bash
Once you have added /usr/local/bin/bash to the end of the file, use ctrl+x to exit nano (don't forget to save). For this change to take affect, you may have to reboot your system before attempting to change your default login shell. There's a good chance that /usr/local/bin/bash will not show up as an option following the graphical system preferences steps listed above; so, just use the terminal again to change your default login shell.
Bash:
$ chsh -s /usr/local/bin/bash
Notice how this command is not, and should not be executed via sudo; doing so will have an impact on the root user. Aside from that heads up, that's it; you should now be using your newly compiled bash by default! Please keep in mind that these instructions are subject to change with future releases of bash; so, if you're reading this in the future, consult more current documentation. I will attempt to keep this thread up-to-date as time goes on.
Attachments
Last edited: