How do I tell what type my shell is
Asked Answered
H

8

28

How can I tell what type my shell is? ie, whether it's traditional sh, bash, ksh, csh, zsh etc.

Note that checking $SHELL or $0 won't work because $SHELL isn't set by all shells, so if you start in one shell and then start a different one you may still have the old $SHELL.

$0 only tells you where the shell binary is, but doesn't tell you whether /bin/sh is a real Bourne shell or bash.

I presume that the answer will be "try some features and see what breaks", so if anyone can point me at a script that does that, that'd be great.

Hardison answered 2/3, 2011 at 11:11 Comment(3)
possible duplicate of How to determine the current shell i'm working on ?Scholasticate
Thanks, that other post has some useful lists of env vars to check.Hardison
See also unix.stackexchange.com/questions/71121/…Paddock
J
25

This is what I use in my .profile:

# .profile is sourced at login by sh and ksh. The zsh sources .zshrc and
# bash sources .bashrc. To get the same behaviour from zsh and bash as well
# I suggest "cd; ln -s .profile .zshrc; ln -s .profile .bashrc".
# Determine what (Bourne compatible) shell we are running under. Put the result
# in $PROFILE_SHELL (not $SHELL) so further code can depend on the shell type.

if test -n "$ZSH_VERSION"; then
  PROFILE_SHELL=zsh
elif test -n "$BASH_VERSION"; then
  PROFILE_SHELL=bash
elif test -n "$KSH_VERSION"; then
  PROFILE_SHELL=ksh
elif test -n "$FCEDIT"; then
  PROFILE_SHELL=ksh
elif test -n "$PS3"; then
  PROFILE_SHELL=unknown
else
  PROFILE_SHELL=sh
fi

It does not make fine distinctions between ksh88, ksh95, pdksh or mksh etc., but in more than ten years it has proven to work for me as designed on all the systems I were at home on (BSD, SunOS, Solaris, Linux, Unicos, HP-UX, AIX, IRIX, MicroStation, Cygwin.)

I don't see the need to check for csh in .profile, as csh sources other files at startup. Any script you write does not need to check for csh vs Bourne-heritage because you explicitly name the interpreter in the shebang line.

Jujutsu answered 15/5, 2011 at 20:59 Comment(2)
Thanks, that's exactly the sort of thing I was looking for.Hardison
in-ulm.de/~mascheck/various/whatshell looks pretty comprehensive. /via unix.stackexchange.com/questions/71121/…Paddock
F
21

Try to locate the shell path using the current shell PID:

ps -p $$

It should work at least with sh, bash and ksh.

Fluker answered 2/3, 2011 at 11:20 Comment(1)
Unfortunately all that does is tell me what the binary is called, not what type of shell it is.Hardison
V
6

If the reason you're asking is to try to write portable shell code, then spotting the shell type, and switching based on it, is an unreliable strategy. There's just too much variation possible.

Depending on what you're doing here, you might want to look at the relevant part of the autoconf documentation. That includes an interesting (and in some respects quite dismal) zoology of different shell aberrations.

For the goal of portable code, this section should be very helpful. If you do need to spot shell variants, then there might be some code buried in autoconf (or at least in one of the ./configure scripts it generates) which will help with the sniffing.

Ventris answered 2/3, 2011 at 13:32 Comment(1)
Thanks, that looks like a useful linkHardison
S
3

You can use something like this:

shell=`cat /proc/$$/cmdline`
Studio answered 2/3, 2011 at 11:18 Comment(6)
That will only work on Linux and only if /proc is mounted/accessible.Terrill
Only if procfs is available. You can probably achieve the same effect by looking at $@.Damick
Even on Linux with /proc it still doesn't work. All it does is tell you the path to the shell, not what the shell is.Hardison
@Hardison What's the difference? "/bin/bash" is bash, "/bin/sh" is sh, "/bin/zsh" is zsh...Anesthesiologist
On Linux, /bin/sh is quite often bash. This is also the case on at least some versions of OS X.Hardison
Apart form all the other critique, forking a cat process is just insane, when read -r shell < /proc/$$/cmdline would do the trick with about 1/1000 of the CPU cycles.Jujutsu
C
2

The system shell is the thing you see when you open up a fresh terminal window which is not set to something other than bash (assuming this is your default SHELL).

echo $SHELL

Generally, you can find out all the constants defined by running

set

If the output is a lot of stuff then run

set | less

so you can scroll it from the top of the command line or

set > set.txt

To save the output to a file.

Invoking a different interactive shell to bash in your terminal does not mean that your system shell gets changed to something else i.e. your system shell is set to bash although you invoke a csh shell from a bash shell just that one session.

The above means that typing /bin/csh or /bin/python in bash or whatever does not set the system shell to the shell you invoked, at all.

If you really want to see the SHELL constant change then you need to set it to something else. If successful you should see the new shell whenever you open a fresh terminal...

Carleton answered 20/4, 2014 at 16:41 Comment(8)
As I pointed out in the question, $SHELL isn't set by all shells.Hardison
@Hardison your post was impossible to read until I fixed it. In any case, I am explaining how you find the defined constants on your desktop. if you want to know what shell is set then you need to check $SHELL or give an example of why that does not work for you.Carleton
Other people could read it just fine. But you want an example? OK, on this 'ere Mac, if I start in bash, which sets $SHELL, and then type 'csh' I end up in a different shell but with $SHELL unchanged.Hardison
@Hardison ok I see why you are confused now. The above should clarify.Carleton
SHELL is an indication of preference and not state. See unix.stackexchange.com/questions/45458/…Jacy
@TomDuckering where did I say it was a state?Carleton
@magpie Nowhere. My comment is a clarification and not a critique.Jacy
@TomDuckering if you want to edit the answer go ahead.Carleton
D
1

Oh, I had this problem. :D

There is a quick hack, use ps -p $$ command to list the process with PID of the current running process -- which is your SHELL. This returns a string table structure, if you want, you can AWK, or SED the shell out...

Domestic answered 2/3, 2011 at 11:23 Comment(1)
At best this will tell you the path to the shell, which isn't what I was asking for.Hardison
D
0

It's old thread but...

In GNU environment You can sh --help and get something like

BusyBox v1.23.2 (2015-04-24 15:46:01 GMT) multi-call binary.

Usage: sh [-/+OPTIONS] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS]]

Unix shell interpreter

So, the first line is shell type =)

Donnettedonni answered 10/2, 2016 at 13:32 Comment(4)
That only tells you what sh is, not what your shell is. Consider this ... $ csh % sh --help GNU bash, version 3.2.57(1) ... GRARGH, STUPID WEBSITE FORMATTINGHardison
Try $(echo $0) --help ;)Donnettedonni
% $(echo $0) --help new line goes here stupid website formatting Illegal variable name.Hardison
It seems tcsh cannot expand $(<command>) notation, so more portable code will be `echo $0` --help or even `printf $0` --help. Also, note that csh is not sh compatible, so syntax may differ.Donnettedonni
B
0

You can use the following command in most of the Linux environment:

ls -l /proc/$$/exe

More discussion see this post.

Bedel answered 21/9, 2023 at 22:23 Comment(1)
Not on a Mac you can't. Nor on FreeBSD, OpenBSD or IllumOS. But even on Linux it still doesn't tell me whether the shell is bash or csh or whatever, it only tells me the name of the binary.Hardison

© 2022 - 2025 — McMap. All rights reserved.