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