Linux check what shell

How to test what shell I am using in a terminal?

I am not so sure that «shell» has a well defined meaning. For example, you might run xterm -e /bin/cat but I am not happy calling /bin/cat a shell.

13 Answers 13

Several ways, from most to least reliable (and most-to-least «heavy»):

  1. ps -p$$ -ocmd= . (On Solaris, this may need to be ps -p$$ -ofname= and on macOS and on BSD should be ps -p$$ -ocommand= .)
  2. Check for $BASH_VERSION , $ZSH_VERSION , and other shell-specific variables.
  3. Check $SHELL ; this is a last resort, as it specifies your default shell and not necessarily the current shell.

I don’t like $0 because it’s more complicated: (1) it may be just the basename, (2) it may have ‘-‘ on the front to designate it as a login shell.

@geekosaur: maybe so, but $0 still seems more useful than $SHELL : wouldn’t you agree? You could always pipe it through sed to remove the ‘-‘.

If you’re running tcsh , $tcsh and $version will be set. These are shell variables, not environment variables. If you’re running a non-tcsh version of csh , I don’t think there are any distinctive variables. And of course the syntax used to check variables differs between csh/tcsh on the one hand, and sh/ksh/bash/zsh on the other.

I’ve found that the following works in the four shells I have installed on my system (bash, dash, zsh, csh):

The following works on zsh, bash, and dash, but not on csh:

I think that @jiliagre’s answer is probably would I would use today. On fish %self can be used in place of $$

As the question asks for the shell used and does not talk about the potential arguments passed to it, here is a way that avoid showing them:

There are two really simple ways:

  • -h or finishing all options with = for not showing any header.
  • -o comm for showing only the process basename ( bash instead of /bin/bash ).
  • -p list only process whith PID form list suplied.

This /proc/PID/exe links to the file being executed, which in this case would point to /bin/bash, /bin/ksh, etc. For getting only the name of the shell you can just use

basename $(readlink /proc/$$/exe) 

The usage of /proc is really useful via the /proc/self , which links to the PID of the current command.

basename $(readlink /proc/$$/exe) is Korn/POSIX shell syntax. Won’t work in csh/tcsh/rc/es/akanga/fish. $$ won’t work in rc / es / akanga / fish .

basename $(readlink /proc/$$/exe) is the only command here that could work for me in a docker image with no ps installed.

A note about some lighter implementations (Android phones, busybox, etc.): ps doesn’t always have support for the -p switch, but you can accomplish the search with a command like ps | grep «^$$ » . (This grep regex will uniquely identify the PID, so there will not be any false positives.)

ps | grep $$ can still give false positives if, for example, your current process is 1234 and there’s a process 12345 .

A mix of all the other answers, compatible with Mac (comm), Solaris (fname) and Linux (cmd):

ps -p$$ -o cmd="",comm="",fname="" 2>/dev/null | sed 's/^-//' | grep -oE '\w+' | head -n1 

this gives me my current directory name; also, under csh and tcsh it gives me Ambiguous output redirect.

This is also what Anaconda uses (version 2022.05) in it’s [env]/bin/activate script to detect shell type. A comment in that file explicitly links to this answer.

Читайте также:  Linux patch one file

If you have it saved in your environment variables you can use the following:

For accuracy in many different shells you should use

What is that number?

It’s the process id of the current shell.

$ expands to the same value as the current shell.

$$ process ID of the parent in a sub shell

If you only want then name of the shell you could use

ps -p $$ | awk '1)print>' | awk '$0=$NF' | tr -d - 

In a nutshell we are taking the output of the process sub shell and piping it to some formatting tools awk, sed and tr all work for this, removing the first 3 columns, the first line of output, and then the — gives just the name of the shell. Consider putting that into a function for ease later.

That will most likely return the pathname of the shell executable of your login shell. It is not certain that the login shell is what you are currently running though.

I set $MYSHELL for future tests in my shell-agnostic ~/.aliases :

unset MYSHELL if [ -n "$ZSH_VERSION" ] && type zstyle >/dev/null 2>&1; then # zsh MYSHELL=`command -v zsh` elif [ -x "$BASH_VERSION" ] && type caller >/dev/null 2>&1; then # bash MYSHELL=`command -v bash` elif [ -x "$shell" ] && which setenv |grep -l builtin >/dev/null; then # tcsh echo "DANGER: this script is likely not compatible with C shells!" sleep 5 setenv MYSHELL "$shell" fi # verify if [ ! -x "$MYSHELL" ]; then MYSHELL=`command -v "$(ps $$ |awk 'NR == 2 < print $NF >')"` [ -x "$MYSHELL" ] || MYSHELL="$" # default if verify fails fi 

The tcsh section is likely unwise to roll into a POSIX-style script since it’s so radically different (thus the warning and five second pause). (For one, csh -style shells can’t do 2>/dev/null or >&2 , as noted in the famous Csh Programming Considered Harmful rant.)

Источник

How do I check which shell I am using?

Please note that terminal is interface to the shell (which at one point used to be actually physical interface), and shell is not terminal — it is a command interpreter. See also askubuntu.com/a/640105/295286

9 Answers 9

You can type the following command in your terminal to see which shell you are using:

The result will look something similar to the below if you are using the bash (Bourne Again Shell) terminal:

@Mi_Onim $0 is the name of the running process. If you use it inside of a shell then it will return the name of the shell. If you use it inside of a script, it will be the name of the script.

@Anwar makes a good point, after you get the shell name from echo $0 , ls -l `which ` to see if it is symlinked to another shell binary.

To find the shell you have on the default environment you can check the value of the SHELL environment variable:

To find the current shell instance, look for the process (shell) having the PID of the current shell instance.

To find the PID of the current instance of shell:

Now to find the process having the PID:

$SHELL is the default shell for the system (or user), which is usually (but not necessarily) the shell that is actually being used at any given moment.

echo $SHELL gave me /bin/csh and ps -p $$ gave me 22673 pts/1 00:00:00 bash . Kingmilo explained (above) why they are not the same.

To grab ONLY the shell name for the current shell in a way portable between gnu & bsd ps versions, this works well: ps -cp «$$» -o command=»»

$SHELL gives you the default shell. $0 gives you the current shell.

For example: I have bash as my default shell, which I use for my Terminal App. But for my iTerm2 app, I use the command as the window opens: /bin/ksh .

So my $0 gives me /bin/ksh on iTerm2. $SHELL gives me /bin/bash on iTerm2. $0 , $SHELL gives me /bin/bash on Terminal

For me, I have zsh installed and it’s the current default, to change to bash, all I have to do type bash in the terminal. To switch back to zsh, type zsh

You don’t want to keep going back and forth that way because you stack up shell within shell within shell, and a fresh context within each. In general it’s best to type ctrl-d or exit to return to the previous shell.

Best answer, should be chosen as answer. Agree to yousuf Azad on changing shell, but also agree to stacking issue indicated by Phill Apley. My default is also zsh , but to switch I type bash , and to return back I can simply do exit or ctrl + D

The other answers tend to be using shell specific features, but we are trying to discover which shell we are using, so they assume the answer to the problem. For example none of the answers will work on fish.

sh -c 'ps -p $$ -o ppid=' | xargs ps -o comm= -p 

Instead use the $$ syntax in an invocation of sh, but then we are looking for the PPID not the PID. Use the PPID to find the cmd.

sh -c 'ps -p $$ -o ppid=' | xargs -I'<>' readlink -f '/proc/<>/exe' 

Thanks for improvement @muru

You ca use ppid= / cmd= to omit the headers (and so the tail -1 s), and consider looking at /proc/. /exe to see what file is being run (since the cmd output can be manipulated by whatever ran the shell).

Apparently this does not work in busybox, due to non posix compliance: ref: github.com/broadinstitute/cromwell/pull/…

this solution solves the problem of assuming the shell but introduces the problem of assuming the OS. The BSD version of readlink shipped with macOS (and presumably other BSD Distros) uses -f to specify «format» which is a printf style string that must start and end with % and has a variety of templating options.

Great answer, @EvanBenn, thanks! Here is a tiny modification to allow it to work with shells like BusyBox , where the -p arg to ps isn’t supported, and where there aren’t a whole lot of other utilities like cut to help. Code: set — $(ps -o pid,ppid | grep -E «^ *$$»); readlink -f «/proc/$<2>/exe» . I’m using your method to determine the shells used on a bunch of «free online Linux shell» websites, and it’s great!

The original post asked three questions. The answers given do cover the first question, «When I open a terminal window, which shell is opened by default?» They also answer a question which was NOT asked, namely «How can I find out which shell is currently running in the terminal?» However, as far as I can see nobody has answered either the second or third questions originally asked, namely «How do I check how many shells are installed?» and «How do I change the shell used from my account?»

    To answer «How do I check how many shells are installed?» the following command will list all the available shells:

# /etc/shells: valid login shells /bin/sh /bin/dash /bin/bash /bin/rbash 

To know which is the default shell for your user, you can run:

For example if you’re using Bash you should get the following output:

If you didn’t change any configuration it should be Bash since Bash it’s the default shell on Ubuntu.

@kol there was before edit. Please also note $SHELL is the default shell for the system (or user), which is usually (but not necessarily) the shell that is actually being used at any given moment.

@kingmilo Reading the answer again i think i understand what is your concern, probably i didn’t express myself well. I clarified the meaning of «currently» in my answer

@frederickjh fish is a bit of an odd one out here. The $$ variable is actually defined by POSIX and will work on the vast majority of shells. Fish has decided not to follow the standard here so I think it’s fair to ignore it. I can confirm that $$ works as expected in sh, dash, bash, zsh, ksh, ash, tcsh and csh. In fact, off the top of my head I can’t think of any other shell except fish where it doesn’t work.

You may not want to know the current shell’s name (e.g. -bash , bash , zsh , etc., from echo $0 ), nor default shell’s executable path (from echo $SHELL ), but rather the current shell’s executable path (especially useful e.g. if you have more than one version of Bash installed).

To do this you can use lsof -p «$$» or with some extra coding to extract just the required info:

lsof -p "$$" | grep -m 1 txt | xargs -n 1 | tail -n 1 

Example output for Bash installed via Homebrew:

/usr/local/Cellar/bash/5.1.8/bin/bash 

The above is different from echo $SHELL , both because the above is for the shell which is currently running rather than the user’s default shell, and also because the above gives the executable after any symlinks have been expanded. E.g. for the same Bash install as above, echo $SHELL gives /usr/local/bin/bash .

EDIT: If you need to allow for possible space characters in the shell’s path, use lsof -p «$$» | grep -m 1 txt | xargs -n 1 | tail -n +9 | xargs instead.

To address your third question, «How do I change the shell used from my account?», the answer is to use chsh .

You will use a program called chsh. There is a interactive method and non-interactive method. Type the following into your terminal:

INTERACTIVE METHOD

This results in a brief dialog in which the user is prompted first for their password and then for the full path of the desired new shell.

Caution should be exercised when changing one’s default shell because it is possible to make an error that only the root user (i.e., system administrator) can repair (although it should be easy for a skilled user to repair it on a home system). In particular, it is important to first test the shell temporarily in the current session and then to make certain that a valid shell name is being entered when making the permanent change.

NON-INTERACTIVE METHOD

I will use csh as again an example.

The -s sets it for you without having to go into the editor to do it.

Once this is executed successfully, then echo $SHELL will still say that you are in the same shell as before. However, you need to log out and back in for the change to take effect. Now do echo $SHELL . You should see it shows the new shell.

Источник

Оцените статью
Adblock
detector