In Terminal, how can you determine which shell is actually running?

Using Terminal on OS X 10.11.4, initializing Terminal opens a new window running bash (by default). As I understand it, inputting echo $SHELL should output the shell that said command is submitted to. So, why do I get this output after switching from bash to tcsh?

[<dir>] <username>$ tsch
[<dir>] <username>% echo $SHELL
/bin/bash

Under csh family shells, you'll got your running shell with this command:

% echo $shell

If csh was run, directly or undirectly, from a Bourne family shell that had its SHELL variable exported, the latter being the common case, the SHELL variable would stay untouched so echo $SHELL will still show the its previous value which would be confusing.

This is what is happening to you, one of the parent processes of your tcsh session was bash. If bash is started with the SHELL variable unset, it sets it to the path to bash, despite what its documentation states. Note that launching a new Bourne shell family wouldn't have changed either the SHELL variable if set. SHELL is definitely not the way to identify what shell you are running, just to known which shell is your default shell when in a POSIX environment.

A portable way to know what shell is currently running would be:

ps -o comm= -p $$

However, the latter command assumes $$ is set to the current process PID, which unfortunately some exotic shells like fish break. An even more portable way that workarounds this issue is:

env sh -c 'basename $(ps -o comm= -p $(ps -o ppid= -p $$))'

It depends on the shell you are running in.

If it is a POSIX confirming shell e.g. bash, ash,ash, sh, and some others e.g. csh, tcsh then echo $0 will return the shell's name

e.g.

~ $ bash
bash-3.2$ echo $0
bash

or

~ $ ksh
$ echo $0
ksh

However not all shells are POSIX e.g. I used to use ipython shell profile and now fish


Another way would be to check which TTY your terminal is attached to and check which shell is running on that tty. Then you could look at the PID (Process ID) and PPID (Parent Process ID) in case your shell has spawned another shell as a child process:

MacBook:~$ w
15:16  up 8 days, 16:11, 2 users, load averages: 1.26 1.22 1.24
USER     TTY      FROM              LOGIN@  IDLE WHAT
myuser   console  -                19Apr16 8days -
myuser   s000     -                15:15       - w
MacBook:~$ ps -ef | grep s000
UID   PID  PPID   C STIME   TTY           TIME CMD
    0 23865   293   0  3:15PM ttys000    0:00.14 login -pf myuser /bin/bash
  501 23866 23865   0  3:15PM ttys000    0:00.05 -bash
    0 23992 23866   0  3:16PM ttys000    0:00.01 ps -ef
  501 23993 23866   0  3:16PM ttys000    0:00.00 grep s000
MacBook:~$ 

In the example above, using the w command, I've found out that the user myuser is logged in to the console (ignore this one) and also to s000.

I then ran ps -ef and just looking at the PID and PPID columns, I can see that login (PID 23865) has executed bash (PID 23866, PPID 23865), which then ran two processes: ps -ef (PID 23992, PPID 23866) and grep s000 (PID 23993 PPID 23866).

If, for some reason, I executed tcsh from bash, running the above commands would still allow me to see which shell is my current command executed by.


When you start a terminal session in OS X the login utility is called.

From the man page:

The login utility enters information into the environment (see environ(7)) specifying the user's home directory (HOME), command inter-
preter (SHELL), search path (PATH), terminal type (TERM) and user name (both LOGNAME and USER).

Some shells may provide a builtin login command which is similar or identical to this utility.  Consult the builtin(1) manual page.

Note the options used when the utility is called then read the man page:

ps -ef | grep -w [l]ogin

Some of this information was gleaned from your record in opendirectory.

dscl . -read /Users/your_user_name RecordName UserShell NFSHomeDirectory