Instantly share code, notes, and snippets.

Embed
What would you like to do?
Install Bash version 4 on MacOS X
# Install Bash 4 using homebrew
brew install bash
# Or build it from source...
curl -O http://ftp.gnu.org/gnu/bash/bash-4.2.tar.gz
tar xzf bash-4.2.tar.gz
cd bash-4.2
./configure --prefix=/usr/local/bin && make && sudo make install
# Add the new shell to the list of legit shells
sudo bash -c "echo /usr/local/bin/bash >> /private/etc/shells"
# Change the shell for the user
chsh -s /usr/local/bin/bash
# Restart terminal.app (new window works too)
# Check for Bash 4 and /usr/local/bin/bash...
echo $BASH && echo $BASH_VERSION
# Put this somewhere in your dotfiles to turn on recursive globbing
shopt -s globstar
# Source your dotfiles...
source path/to/dotfiles
# Now you can double glob your way into distant directories
cd some/uportal/project/root
cd **/skins
@srohatgi

This comment has been minimized.

Copy link

srohatgi commented Jun 3, 2014

./configure --prefix=/usr/local

worked for me, otherwise bash was installed in /usr/local/bin/bin/bash

@derhuerst

This comment has been minimized.

Copy link

derhuerst commented May 21, 2015

I added a safety check if /usr/local/bin/bash is already present in /private/etc/shells:

if [ $(cat /private/etc/shells | grep '/usr/local/bin/bash' | wc -l) -eq 0 ]; then
    sudo bash -c 'echo /usr/local/bin/bash >> /private/etc/shells'
fi
@aaronmehar

This comment has been minimized.

Copy link

aaronmehar commented Jun 18, 2016

Avoiding the cats, and wc processing, you can shorten the check; but the check is a good idea.

if [ $(grep -c /private/etc/shells /usr/local/bin/bash) -eq 0 ]; then
    sudo bash -c 'echo /usr/local/bin/bash >> /private/etc/shells'
elif 
   echo '/usr/local/bin/bash seems to exist already in your shell options'
fi
@cfs-pure

This comment has been minimized.

Copy link

cfs-pure commented Jul 15, 2016

You can shorten the if even more by getting rid of test and the equality check by using the return code of grep:

if grep -q /usr/local/bin/bash /private/etc/shells; then

@willbuckner

This comment has been minimized.

Copy link

willbuckner commented Nov 10, 2017

More idiomatically:

if ! grep -q /usr/local/bin/bash /private/etc/shells; then
    echo /usr/local/bin/bash | sudo tee -a /private/etc/shells
else
    echo '/usr/local/bin/bash already found in /private/etc/shells'
fi

Or as a concise one-liner:

grep -q /usr/local/bin/bash /private/etc/shells || echo /usr/local/bin/bash | sudo tee -a /private/etc/shells
@aleclarson

This comment has been minimized.

Copy link

aleclarson commented Feb 26, 2018

Not working for me:

$ echo $BASH
/usr/local/bin/bash

$ $BASH --version
GNU bash, version 4.4.19(1)-release (x86_64-apple-darwin17.3.0)
Copyright (C) 2016 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.

$ echo $BASH_VERSION
3.2.57(1)-release

$ bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)
Copyright (C) 2007 Free Software Foundation, Inc.

Edit: In the Terminal preferences, change "Shells open with" to use /usr/local/bin/bash --login and the $BASH_VERSION will be correct when you open a new window or restart Terminal.

I think you need to alias bash="/usr/local/bin/bash" if you want the bash command to use Bash 4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment