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:

$ echo $SHELL
/bin/bash

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:

$ echo $0
bash

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.

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:

$ cat /proc/$$/cmdline
bash 

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.