34

When I do the brew upgradeI see I do have the newer version. How can I use it?

$ bash -version
GNU bash, version 3.2.51(1)-release (x86_64-apple-darwin13)
Copyright (C) 2007 Free Software Foundation, Inc.
$ brew upgrade bash
Error: bash-4.2.45 already installed
$ which bash
/bin/bash

I do see I have

/usr/local/Cellar/bash/4.2.45/bin

but when i do

$ /usr/local/Cellar/bash/4.2.45/bin/bash

I am still in

$ bash -version
GNU bash, version 3.2.51(1)-release (x86_64-apple-darwin13)
Copyright (C) 2007 Free Software Foundation, Inc.
08:06:45 mdurrant w89123148q1 /usr/local/Cellar/bash/4.2.45/bin master

The contents of /etc/shells are:

/usr/local/Cellar/bash/4.2.45/bin/bash  # (I added this)
/usr/local/bin/bash
/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh

chsh didn't seem to do what I hoped:

$ chsh -s /usr/local/Cellar/bash/4.2.45/bin/bash
Changing shell for mdurrant.
Password for mdurrant:
chsh: /usr/local/Cellar/bash/4.2.45/bin/bash: non-standard shell
$ bash --version
GNU bash, version 3.2.51(1)-release (x86_64-apple-darwin13)
Copyright (C) 2007 Free Software Foundation, Inc.

I have the file here:

$ l /usr/local/Cellar/bash/4.2.45/bin/bash
-r-xr-xr-x  1 mdurrant  admin  699688 Apr 14 19:54 /usr/local/Cellar/bash/4.2.45/bin/bash*

I've yet to actually see the new bash version for anyway that I try interactively to invoke it.

$ echo $BASH_VERSION shows

3.2.51(1)-release

I tried using dscl and did

> change Local/Default/Users/mdurrant UserShell /bin/bash /usr/local/Cellar/bash/4.2.45/bin/bash

but got

<main> attribute status: eDSAttributeNotFound
<dscl_cmd> DS Error: -14134 (eDSAttributeNotFound)

and now list shows

> UserShell: /usr/local/Cellar/bash/4.2.45/bin/bash
IKavanagh
  • 6,089
  • 11
  • 42
  • 47
Michael Durrant
  • 93,410
  • 97
  • 333
  • 497
  • Why don't you change the login shell (using `chsh` or equivalent on Mac) instead? – devnull Apr 14 '14 at 12:15
  • I tried. didn't work. adding to above – Michael Durrant Apr 14 '14 at 12:17
  • Not sure if `/usr/local/bin/bash` and `/bin/bash` are the same. If you want to keep both the versions (3.2.x and 4.2.x) around, then have `/usr/local/bin/bash` point to the older one and `/bin/bash` point to the newer one. – devnull Apr 14 '14 at 12:19
  • 1
    The error using `chsh` can be fixed by adding the path to new bash in `/etc/shells`. – devnull Apr 14 '14 at 12:21
  • Just put `/usr/local/Cellar/bash/4.2.45/bin/bash` in `/etc/shells` and then `chsh` – Reinstate Monica Please Apr 14 '14 at 12:21
  • 2
    possible duplicate of [Unable to update my Bash in Mac by MacPorts](http://stackoverflow.com/questions/791227/unable-to-update-my-bash-in-mac-by-macports) – devnull Apr 14 '14 at 12:24
  • unfortunately the MacPorts question/answer was not my issue. I tried again: `brew install bash`, adding /usr/local/Cellar/bash/4.2.45/bin/bash to /etc/shells and run doing chsh -s /usr/local/Cellar/bash/4.2.45/bin/bash but nothing changed. Still running 3.2.51 – Michael Durrant Apr 15 '14 at 00:04
  • Your user is hosed up. I've changed back and forth from /bin/bash to /usr/local/bin/bash and only `sudo su - $USER` is needed to get the $BASH_VERSION to change as expected. – bmike Apr 15 '14 at 00:31

5 Answers5

55

bash --version (or bash -version) will NOT report the CURRENT shell's version, but the version of the bash executable that comes FIRST IN THE $PATH.

[Note: OSX 10.10 (Yosemite) is the first OSX version where /usr/local/bin is placed BEFORE system paths such as /bin in the $PATH. Up to 10.9, system paths came first. Thus, at the time the OP asked his question, bash --version reported the SYSTEM's bash's version (/bin/bash), not the Homebrew-installed version (/usr/local/bin/bash)]

If you want to know the current Bash shell's version, use:

echo $BASH_VERSION

In other words: your shell may well have been changed successfully - your test was flawed.


You can use chsh to change the current user's shell, as follows:

[Update: Switched to using /usr/local/bin/bash rather than a specific, versioned path in /usr/local/Cellar/bash/<version>/bin/bash, as Homebrew will automatically keep the symlink at /usr/local/bin/bash pointed to the most recent installed version. Tip of the hat to @drevicko.]

 # First, add the new shell to the list of allowed shells.
sudo bash -c 'echo /usr/local/bin/bash >> /etc/shells'
 # Change to the new shell.
chsh -s /usr/local/bin/bash 

Note that you'll be prompted for your password.
Any terminal tab/window you create from that point on will already use the new shell.

Bonus tip from @bmike: If you want to replace the current shell instance with an instance of the new shell right away, run:

exec su - $USER  # instantly replaces current shell with an instance of the new shell

Note that you'll be prompted for your password again.


Alternatively, use dscl - the OSX Directory Services CLI - to change the current user's shell; this is more cumbersome, however.

To examine the current user's shell, use:

dscl . -read /Users/$USER UserShell  # e.g. (default): 'UserShell: /bin/bash'

or, more simply, echo $SHELL, which outputs only the file path (e.g., /bin/bash).

To change the current user's shell to, e.g., /usr/local/bin/bash, use:

sudo dscl . -change /Users/$USER UserShell /bin/bash /usr/local/bin/bash

Note:

  • the penultimate argument must be the value currently in effect.
  • it is NOT necessary for the new value to be contained in /etc/shells for interactive use, but the comments in /etc/shells state Ftpd will not allow users to connect who are not using one of these shells.
  • simply quit and restart Terminal.app (or iTerm.app) for the change to take effect - verify the new shell with echo $BASH_VERSION - a reboot is NOT required.

Explanation of errors encountered by the OP:

  • chsh: /usr/local/Cellar/bash/4.2.45/bin/bash: non-standard shell implies that /usr/local/Cellar/bash/4.2.45/bin/bash was not - not yet, or not in this exact form - listed in /etc/shells.
  • <main> attribute status: eDSAttributeNotFound: this dscl error occurs when the penultimate (next-to-last) argument specified for the -change command does not match the current attribute value - it is an - admittedly strange - requirement that an attribute's current value be specified in order to change it.

While the question suggests that both conditions were met, I suspect that they weren't met at the right times, due to experimentation.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • You are correct and echoing the version is probably the source of this error. I still wonder at the `chsh` error - perhaps that's due to the "Cellar" in the `/etc/shells`? – bmike Apr 15 '14 at 00:20
  • @bmike: The `chsh` error `non-standard shell` normally indicates that the specified shell is NOT in `/etc/shells`; however, you can bypass the problem by using `dscl` - see my updated answer. – mklement0 Apr 15 '14 at 03:00
  • I agree that normally that error is due to /etc/shells, but the OP has lines for both potential homebrew shells so unless there's some oddball permissions on the file - it's likely some other corruption was foiling steps that normally would work. – bmike Apr 15 '14 at 03:03
  • 1
    @bmike: I suspect that the OP tried various things at various times, so the sequence listed in the question may not reflect the actual conditions - the OP's eventual own answer seems to confirm that. I've added an explanatory section to my answer. – mklement0 Apr 15 '14 at 03:18
  • @bmike: Neat `su` trick, I've added it to the answer; seems that prefixing `su` with `sudo` is not needed - it prompts on demand. (Another caveat is that exiting out of the new shell brings you back to the old one). – mklement0 Apr 15 '14 at 04:06
  • @drevicko: You are absolutely correct, thanks for pointing that out - answer updated. – mklement0 Nov 19 '14 at 03:59
3

The answer was that, yes, I needed to:

  • brew install bash
  • add the path to /etc/shells
  • use chsh -s: chsh -s /usr/local/Cellar/bash/4.2.45/bin/bash
  • possibly use dscl to set the shell, i.e. within dscl type

    > change Local/Default/Users/<username> UserShell /bin/bash /usr/local/bin/zsh

most importantly:

  • quit the terminal (really close the app, not just its windows).
  • reboot

echoing $BASH_VERSION after rebooting showed 4.2.45(2)-release

mklement0
  • 382,024
  • 64
  • 607
  • 775
Michael Durrant
  • 93,410
  • 97
  • 333
  • 497
2

Current versions of iTerm2 allow for a simpler & less intrusive change. In Preferences > Profiles > General, under "Command" change "Login shell" to eg.:

/usr/local/bin/bash -l
n.caillou
  • 1,263
  • 11
  • 15
  • This helped for me. Either for historic reasons or by default for me this setting was explicitly set to "/bin/bash", which means all other magic is absolutely useless, as we explicitly tell iTerm to start with this bash executable. I just changed it to "Login Shell" and it worked, as I did all the steps of installing the new bash version properly. – Innokenty Aug 19 '21 at 12:15
1

You shouldn't have to do anything else than to run:

echo /usr/local/bin/bash|sudo tee -a /etc/shells;chsh -s /usr/local/bin/bash

After that iTerm and Terminal should use /usr/local/bin/bash for new shells.

chsh, dscl, and the Users & Groups preference pane all modify /var/db/dslocal/nodes/Default/users/$USER.plist.

Lri
  • 26,768
  • 8
  • 84
  • 82
1

Assuming one only wishes to change the shell used by iTerm (and not the user's default shell), the following straightforward solution is possible as of version 3.4 (see iTerm2#3624330):

In iTerm, under Preferences > Profiles > General > Command select Custom Shell from the dropdown, and put the path to your desired shell (e.g. /usr/local/bin/bash) in the "Enter full path to shell" field to run it as a login shell.

Also refer to the General Profile Preferences section of the iTerm2 Documentation.

Spencer Mathews
  • 135
  • 1
  • 7