2

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
2
  • Try echo $0 $SHELL is set in your .profile as an environment variable.
    – Allan
    Apr 27 '16 at 22:53
  • @Allan - echo $0 just gives me a blank line - there are non POSIX shells
    – mmmmmm
    Apr 27 '16 at 22:58
4

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 $$))'
8
  • Right: but as per my question, why is this outputting /bin/bash if I (supposedly) have switched from the default bash to tcsh?
    – JDQ
    Apr 28 '16 at 1:19
  • Answer updated. tcsh doesn't touch the SHELL variable so if it has a value when tcsh is started, it stays that way.
    – jlliagre
    Apr 28 '16 at 2:28
  • Portable answer posted, ps -o comm= -p $$ should work whatever the shell provided that shell correctly set $$, which tcsh should do.
    – jlliagre
    Apr 28 '16 at 2:51
  • That portable answer fails in fish so I think is a POSIX only answer as well
    – mmmmmm
    Apr 28 '16 at 8:14
  • @Mark no, it is not POSIX only given the fact it works with csh, tcsh and the likes which are notoriously non POSIX. Answer updated anyway with a command that should work with much more shells, including fish.
    – jlliagre
    Apr 28 '16 at 9:06
4

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

3
  • Ah, yes: I entered echo $0 and got the expected output: tcsh. I'm going to go ahead and accept this answer as it solves the specific example that I gave. That being said, do you know if tcsh (or any shell for that matter) is running in some sort of "emulated" state when I use tcsh to switch from the default bash rather than changing the default shell in the Terminal preferences to tcsh (or some other installed shell)?
    – JDQ
    Apr 28 '16 at 1:24
  • @WatermarkBranding running tcsh from the command line is the same as running as the default shell (except for being called as a login shell by Terminal)
    – mmmmmm
    Apr 28 '16 at 8:28
  • I really do appreciate your prompt response (and one which helped solve the example that I gave). That said, in all fairness, jllagre' response more thoroughly answers the question. I'm going to upvote your answer anyhow. Best.
    – JDQ
    Apr 28 '16 at 18:23
2

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.

1

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

You must log in to answer this question.

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