How to determine the current shell i am working on ?

Does ps command output will alone do ?

How to do this in different flavors of UNIX ?

+13  A: 

1) There are 3 approaches:

  • echo $0 - will print the program name... which in the case of shell is the actual shell

  • ps -ef|grep $$|grep -v grep - will look for current process ID in teh list of running processes. Current process being shell, it will inlcude shell.

    This is not 100% reliable as you might have OTHER processes whose ps listing includes the same number as shell's process ID, especially if that ID is a small #.

    It also has the same problem as the other 2 approaches - it can be fooled if the executable of the shell is /bin/sh but it's really a renamed bash, for example. So those 2 issues answer your second question of whether ps output will do.

  • echo $SHELL The path to the current shell is in SHELL variable for any shell. The caveat for the last one is that if you launch a shell explicitly as a subprocess (e.g. it's not your login shell) you will get you login shell's value instead - if that's a possibility, use the ps or $0 approach.

2) However, if the executable is not matching real shell (e.g. /bin/sh is actually bash or ksh), you need heuristics. Here are some environmental variables specific to various shells:

  • $version is set on tcsh

  • $BASH is set on bash

  • $shell (lowercase) is set to actual shell name in csh or tcsh

  • $ZSH_NAME is set on zsh

  • ksh has $PS3 and $PS4 set, whereas normal Bourne shell (sh) only has $PS1 and $PS2 set. This generally seems like the hardest to distinguish - the ONLY difference in entire set of envionmental variables between sh and ksh we have installed on Solaris boxen is $ERRNO, $FCEDIT, $LINENO, $PPID, $PS3, $PS4, $RANDOM, $SECONDS, $TMOUT.

${.sh.version} is set on ksh93
`ps -p $$` as [Matthew Slattery]( points out. For `ksh`: `echo $KSH_VERSION` or `echo ${.sh.version}`.
Dennis Williamson
@Dennish - my ksh right now doesn't have KSH_VERSION set. and `echo ${.sh.version}` returns "Bad Substitution". See my solution above
@fpmurphy whatever ksh we have installed on Solaris boxen at work, obviously predates ksh93 as it odesn't have that set. Matter of fact, the ONLY difference in entire set of envionmental variables between `sh` and `ksh` is `$ERRNO`, `$FCEDIT`, `$LINENO`, `$PPID`, `$PS3`, `$PS4`, `$RANDOM`, `$SECONDS`, `$TMOUT`.
@DVK Currently Solaris has a highly customized version of ksh88. The POR is to move to ksh93 for the next release. See for more information.
@fpmurphy - thx!

Try echo $SHELL.

+2  A: 

You can try:

ps | grep `echo $$` | awk '{ print $4 }'


echo $SHELL
+1, pretty slick :)
+5  A: 

ps is the most reliable method. The SHELL envar is not guaranteed to be set and even if it is, it can be easily spoofed

+1 $SHELL is the default shell for programs that need to spawn one. It doesn't necessarily reflect the shell that's currently running.
Jim Lewis
+2  A: 
echo $$ # Gives the Parent Process ID 
ps -ef | grep $$ | awk '{print $8}' #use the PID to see what the process is.


It's not the parent process - it's the current process.
Dennis Williamson
+4  A: 

ps -p $$

should work anywhere that the solutions involving ps -ef and grep do (on any Unix variant which supports POSIX options for ps) and will not suffer from the false positives introduced by grepping for a sequence of digits which may appear elsewhere.

Matthew Slattery
Some shells have their own builtin version of `ps` which may not understand `-p` so you may need to use `/bin/ps -p $$`.
Dennis Williamson
All the shells I'm familiar with understand `$$` except for `fish` with which you would have to use `ps -p %self`.
Dennis Williamson

On Mac OS X (& FreeBSD):

ps -p $$ -axco command | sed -n '$p'