My goal is to run a script, where the shebang line causes bash to be used. Somehow running bash always runs zsh for me, even though I installed bash 5 using Homebrew and Mac (10.15) comes with bash 3.

I would still like zsh to be the default shell.

My goal is to run scripts with bash, and the shebang lines with bash give me zsh, as shown by the syntax that the script recognizes. The use of -c below is just for ease of illustration (as compared to a file with shebang).

Here are my attempts to access bash and the content of /etc/shells

    $ /usr/local/opt/bash/bin/bash -c "echo $SHELL"
    $ whereis bash
    $ /bin/bash -c "echo $SHELL"
    $ /bin/bash -c 'echo $SHELL'
    $ /usr/local/bin/bash -c "echo $SHELL"
    $ /usr/local/bin/bash -c 'echo $SHELL'
    $ 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.
    $ /usr/bin/env bash -c "echo $SHELL"
    $ /bin/bash  -c "ps -p $$"
    PID TTY           TIME CMD
    6775 9 ttys011    0:00.31 -zsh
    $/usr/local/opt/bash/bin/bash -c "ps -p $$"
    PID TTY           TIME CMD
    69799 ttys001    0:00.38 -zsh
    $ /usr/local/bin/bash -c 'ps -p $$'
    PID TTY           TIME CMD
    69985 ttys001    0:00.01 ps -p 69985
    $ /bin/bash -c "echo $0"
    $ /usr/local/opt/bash/bin/bash -c "echo $0"

Also, I created the following file and ran it directly

#!/usr/bin/env bash
# With /bin/bash on the shebang we get the same output
ps -p $$
echo $SHELL
echo $0
echo bash $BASH_VERSION
echo zsh $ZSH_VERSION

The result is:

$ ./bashtest.sh
  PID TTY           TIME CMD
70188 ttys000    0:00.00 /bin/bash ./bashtest.sh
bash 3.2.57(1)-release
  • The last two run bash. What is the actual problem. You are taking guesses and giving no new information – mmmmmm Feb 28 at 18:20
  • 1
    Running bash, fish, etc, etc, is not going to change the value of $SHELL unless a config file is doing something daft. – negacao Feb 28 at 18:22
  • 2
    This is a fabulous example of an XY question. We're on a journey on what you (the OP) think is the issue - probably will get to another problem quite soon... Running bash from within zsh has some baggage for sure so isolating a script to a clean environment can be tricky. (also - everyone I see here is super helpful - so don't take any critical comments as critical of you (you being all of us - not just OP) - this is a deep question needing some clarity for sure) – bmike Feb 28 at 18:32
  • 1
    Basically this asks „why doesn’t $SHELL change when I call another shell“ – nohillside Feb 28 at 19:17

Your examples do not show that the shell you are running is zsh.

What they show is the default shell is zsh and the ps one shows you ran bash from inside a zsh shell.

A way to see the current shell is echo $0 from https://askubuntu.com/questions/590899/how-do-i-check-which-shell-i-am-using However this only works in some cases. It does work if you call bash from zsh as you are doing. It does not work on the non POSIX shells I use e.g. fish and xonsh

$SHELL is the default shell and not what you are running (and that is zsh as you want) login man pages e.g. http://man.openbsd.org/login.1 (or run man login on macOS) $SHELL is set by the login program . However as noted in the man page shells might do other things and also you can (not by default) run a non login shell in Terminal.app and I think that might also have $SHELL set

For the process the $$ is the pid of what the command line sees e.g. trhe shell that runs the bash line you gave.

To see this

  1. Start bash e.g. bash
  2. In the bash shell now run ps -p $$ you get something like
    ~ bash
     bash-5.0$ ps -p $$
      PID TTY           TIME CMD
    28098 ttys000    0:00.01 bash
    bash-5.0$ exit

~ is my zsh prompt. bash is bash 5.0 installled via macports

  • Thank you. I tried echo $0 and still get zsh. See edited body of question. My goal is to run scripts with bash, and the shebang lines with bash give me zsh, as shown by the syntax that the script recognizes. – Joshua Fox Feb 28 at 18:08
  • You are right about running bash and then ps -p $$ My problem,though, is in running scripts with the shebang line, or even in running bash and the filename, and there I seemto get zsh – Joshua Fox Feb 28 at 18:14
  • That is a different question. We need details of that – mmmmmm Feb 28 at 18:17
  • I created a file and ran it. See the edited body. The BASH_VERSION does seem to indicate bash. Is there some direct way of learning whether zsh or bash is running, given that $SHELL , $0 and ps -p $$ do not seem to do it? – Joshua Fox Feb 28 at 18:21
  • Why do you need to know? – mmmmmm Feb 28 at 18:24

Variables in "" get expanded by the running shell, zsh in your case. Use '' instead.

  • Thank you. Good point. But I tried with single-quote, and get the same result. See edited body of question. – Joshua Fox Feb 28 at 18:14
  • @JoshuaFox Many of the people here will have other bash in their path - you are correct in your test script on 11.2.1 - /bin/bash smells very zshy to me in many cases out of the box... – bmike Feb 28 at 18:36
  • Actually, I use #!/usr/bin/env bash. I edited the main body accordingly. – Joshua Fox Feb 28 at 18:49

$SHELL is documented in the bash manal as being your login shell, not the currently running shell. I don't see that variable documented in the zsh manual at all.

There's nothing particular magical about it.

My login shell is fish, and that's what bash sets it to if the variable is unset:

env --unset=SHELL bash -c 'echo $SHELL'    # => /usr/local/bin/fish

If you have a script that is supposed to run under either bash or zsh, then you can check if certain shell-specific variables exist:

echo "this is a bash or zsh script"
if [[ -n $BASH_VERSION ]]; then
    echo "I'm running in $BASH $BASH_VERSION"
elif [[ -n $ZSH_VERSION ]]; then
    echo "I'm running in $ZSH_NAME $ZSH_VERSION"
    echo "I'm running under some other POSIX-type shell"
    ps -ef | grep "$$"

I have a bunch of different shells installed:

$ zsh shell.sh
this is a bash or zsh script
I'm running in zsh 5.8

$ bash shell.sh
this is a bash or zsh script
I'm running in /usr/local/bin/bash 5.0.18(1)-release

$ sh shell.sh
this is a bash or zsh script
I'm running in /bin/sh 3.2.57(1)-release

$ dash shell.sh
this is a bash or zsh script
shell.sh: 2: [[: not found
shell.sh: 4: [[: not found
I'm running under some other shell
  502 31943 31595   0  7:03PM ttys006    0:00.01 dash shell.sh
    0 31944 31943   0  7:03PM ttys006    0:00.00 ps -ef
  502 31945 31943   0  7:03PM ttys006    0:00.00 grep 31943

$ ksh shell.sh
this is a bash or zsh script
I'm running under some other shell
  502 31952 31595   0  7:04PM ttys006    0:00.01 ksh shell.sh
    0 31953 31952   0  7:04PM ttys006    0:00.00 ps -ef
  502 31954 31952   0  7:04PM ttys006    0:00.00 grep 31952
  • So the indicator of the shell your script is running in is a variety of variables specific to each shell rather than a single indicator that states the shell? OK, I can work with that, though it seems a bit kludgy. – Joshua Fox Mar 1 at 6:22
  • 1
    Sad but true. There's no "one true variable". – glenn jackman Mar 1 at 21:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .