- How to test what shell I am using in a terminal?
- 13 Answers 13
- For accuracy in many different shells you should use
- What is that number?
- Determine the Current Shell in Linux
- 1. Overview
- 2. Using the echo Command
- 2.1. echo $SHELL
- 2.2. echo $0
- 3. Using the ps Command
- 4. Viewing the /etc/passwd File
- 5. Using the lsof Command
- 6. Using the readlink Command
- 7. Using /proc/$$/cmdline
- 8. Other Approaches
- 9. Conclusion
- How can I know which shell I am using?
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»):
- ps -p$$ -ocmd= . (On Solaris, this may need to be ps -p$$ -ofname= and on macOS and on BSD should be ps -p$$ -ocommand= .)
- Check for $BASH_VERSION , $ZSH_VERSION , and other shell-specific variables.
- 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.
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.)
Determine the Current Shell in Linux
The Kubernetes ecosystem is huge and quite complex, so it’s easy to forget about costs when trying out all of the exciting tools.
To avoid overspending on your Kubernetes cluster, definitely have a look at the free K8s cost monitoring tool from the automation platform CAST AI. You can view your costs in real time, allocate them, calculate burn rates for projects, spot anomalies or spikes, and get insightful reports you can share with your team.
Connect your cluster and start monitoring your K8s costs right away:
1. Overview
A shell is a program that provides a command-line interface to the operating system.
Linux and Unix-like operating systems provide different shells to the users. Bash (Bourne Again Shell), csh (C Shell), ksh (Korn Shell), and sh (Bourne Shell) are the most common ones.
In this tutorial, we’ll look at various ways to find out the current shell we are working in.
2. Using the echo Command
The echo command in Linux is used to display a line of text or string that is passed to it as an argument. We can also use this command to print the current shell.
2.1. echo $SHELL
The $SHELL variable contains the name of the default shell. We can display its value:
While this approach works in most cases, it is not a reliable way since the currently running shell may not be the default shell.
2.2. echo $0
We can also use the echo command with the $0 variable:
This approach works well on the command line but not from within a script. Within a script file, the $0 variable will not print the current shell. Instead, it prints the name of the file or the program.
3. Using the ps Command
The ps (process status) command provides a snapshot of the currently running processes:
$ ps PID TTY TIME CMD 4467 pts/0 00:00:00 bash 5379 pts/0 00:00:00 ps
The last column CMD in the output shows that the bash shell is currently running.
4. Viewing the /etc/passwd File
/etc/passwd file is a plain text file in Linux which contains users’ account information such as username, user ID, group ID, home directory, and shell.
Using the grep command, we can search this file for a string that starts with the username of the currently logged in user:
$ grep "^$USER" /etc/passwd vroot:x:1000:1000:Vroot:/home/vroot:/bin/bash
The last part of the output shows that the default shell is bash. Again, this is not a reliable approach since the default shell may not always be the current shell.
5. Using the lsof Command
The lsof command lists all the open files of all the running processes. We can use this command with the -p option to only select the files belonging to the current shell’s process ID:
$ lsof -p $$ COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 2796 vroot cwd DIR 253,2 4096 2097153 /home/vroot bash 2796 vroot rtd DIR 253,0 4096 2 / bash 2796 vroot txt REG 253,0 1514000 2490662 /usr/bin/bash bash 2796 vroot mem REG 253,0 8406312 131168 /var/lib/sss/mc/passwd . other lines omitted . bash 2796 vroot 255u CHR 136,0 0t0 3 /dev/pts/0
The $$ is a special parameter that expands to the process ID of the current shell.
The first column COMMAND in the output shows that the running shell is bash.
6. Using the readlink Command
The readlink command prints resolved symbolic links or canonical file names. /proc/[pid]/exe is a symbolic link containing the actual pathname of the executed command with process id pid.
We can use the $$ special parameter to run readlink on the current shell’s process id:
$ readlink /proc/$$/exe /usr/bin/bash
From the pathname to the shell command, we can infer that the shell we are running is bash.
7. Using /proc/$$/cmdline
/proc/[pid]/cmdline is a read-only file that contains the complete command line for any process with id pid.
We can use the $$ special parameter as the pid:
The output shows that we are running the bash shell.
8. Other Approaches
Sometimes none of the approaches we looked at might work. This can happen if the executable does not match the running shell.
In such cases, we can look at some shell-specific environment variables to infer which shell is running.
For instance, if it’s a bash shell, the $BASH variable will be set. Similarly, in the tcsh shell, the $version variable will be set.
The $PS1 and $PS2 variables are set in the sh shell, while the $PS3 and $PS4 variables are set in the ksh shell.
9. Conclusion
In this article, we learned various ways of determining which shell we are currently running in Linux. We looked at examples for several approaches and the limitations of each approach. We also learned about some heuristics we can use when none of the common approaches work.
How can I know which shell I am using?
I am writing a shell script. The tutorial that I am reading have the first line like this : #!/usr/bin/env bash/ but it isn’t working for me. ( error : no such directory ) How can I find out which bash I am using and where is it located? Appreciate for any advice and help. Thanks a lot. It works now. solution is #!/usr/bin/env bash Another problem: Why it just can’t read the word ‘restart’ my code in the start.sh:
#!/usr/bin/env bash/ RESTART="apachectl restart" $RESTART
Usage: /usr/local/apache2/bin/httpd [-D name] [-d directory] [-f file] [-C "directive"] [-c "directive"] [-k start|restart|graceful|graceful-stop|sto p] [-v] [-V] [-h] [-l] [-L] [-t] [-S] Options: -D name : define a name for use in directives -d directory : specify an alternate initial ServerRoot -f file : specify an alternate ServerConfigFile -C "directive" : process directive before reading config files -c "directive" : process directive after reading config files -e level : show startup errors of level (see LogLevel) -E file : log startup errors to file -v : show version number -V : show compile settings -h : list available command line options (this page) -l : list compiled in modules -L : list available configuration directives -t -D DUMP_VHOSTS : show parsed settings (currently only vhost settings) -S : a synonym for -t -D DUMP_VHOSTS -t -D DUMP_MODULES : show all loaded modules -M : a synonym for -t -D DUMP_MODULES -t : run syntax check for config files
why is it like that? it seems that it can read the word restart. Thank you all! I have fixed it now. solution: edit the file in unix (vim/nano and whatever but not in windows)