Don't Use $SHELL to Check Which Shell You Are Using
My preferred shell is zsh
these days. I started with sh
and bash
, then got sidelined into tcsh
after a mathematician friend and colleague at the Max Planck Institute fired up the shell on my Silicon Graphics work station and showed me the cool things it could do.
Then, as Apple started finding its way again and more and more of their machines entered my life I circled back to bash
. This just made my life easier on Darwin (and also, later, any VMs or cloud compute engines that I spun up).
I also started playing around with zsh
some time ago, fascinated by Oh My Zsh. Then, Apple decided to set zsh
as the default shell in macOS starting with Catalina in June 2019 – the company preferred the licensing terms of zsh
over bash
. This means that I now use zsh
80% of the time. But I do flip back and forth between various shells.
So how do you know which shell you are in?
Your first instinct would be to “echo $SHELL
”. Now, $SHELL
is a variable set by the user: in theory it should reflect the shell you are using, but there are situations where it fails. And the reason I wrote this entry is because I have just come across one such situation:
% echo $SHELL
/bin/bash
The above was executed in a zsh
. This happened because:
- I spawned a
zsh
from abash
shell; - I have not yet set any dot-file profiles etc for
zsh
on this machine.
Getting The Truth
There is a foolproof way to get the ground truth.
The first thing to note is that the unix shell variable $
returns the PID (process ID) of the current process. Hence if you echo
’d that in a shell, you’d get the shell’s PID:
% echo $$
50110
This variable can also be used with ps
:
% ps $$
PID TT STAT TIME COMMAND
50110 s001 S 0:00.33 -zsh
Another way, but may be confusing if you are new to the shell, is to use the positional variable $0
.
$0
is where the name of the script of a sourced script, or function name for a script function. (For zsh
see the manpage
zshall
and search for “Parameters Set By The Shell”.)
Hence in:
$ ./myShellScript.sh -i input.file -o output.file
$0
would be ./myShellScript.sh
, $1
is -i
etc.
However, if you echo $0
in the command line, it is the shell that executes it (it really is a shorthand for /bin/[bash, zsh etc] echo $0
), hence will return the shell.
% echo $0
-zsh
Additionally if the shell has a dash -
before the name it indicates that it’s a login shell.
And there you have it: the ground truth.