Command-Line Interface
Shell Scripting
Programming
Terminal Commands
Tech Tips

How to determine the current interactive shell that I'm in (command-line)

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Determining which shell you are currently using is important for writing compatible scripts, setting up dotfiles, and debugging environment issues. The most reliable method is ps -p $$ -o comm=, which queries the process table for the current shell process. Other methods like echo $0, $SHELL, and shell-specific variables each have caveats. $SHELL tells you the default login shell, not necessarily the shell you are currently running in.

Quick Methods

ps -p $$ (Most Reliable)

bash
ps -p $$ -o comm=
# bash
# or: zsh, fish, sh, dash, etc.

$$ is the PID of the current shell process. ps -p $$ -o comm= prints just the command name without headers. This works in bash, zsh, sh, dash, and ksh.

echo $0

bash
1echo $0
2# -bash       (login shell, note the leading dash)
3# bash        (non-login shell)
4# /bin/zsh    (may show full path)

$0 contains the name or path of the current shell. A leading - indicates a login shell. This works in most POSIX shells but not in fish.

$SHELL (Default Shell, Not Current)

bash
echo $SHELL
# /bin/zsh    (your default login shell)

$SHELL is set to your login shell from /etc/passwd or Directory Services. It does NOT change when you switch shells. If your default is zsh but you run bash, $SHELL still says /bin/zsh.

bash
1# Demonstrate the difference
2echo $SHELL     # /bin/zsh (login shell)
3bash            # Switch to bash
4echo $SHELL     # /bin/zsh (still shows zsh!)
5ps -p $$ -o comm=  # bash (correctly shows current shell)

Shell-Specific Variables

Each shell sets unique variables you can test:

bash
1# Bash
2echo $BASH_VERSION
3# 5.2.26(1)-release
4
5# Zsh
6echo $ZSH_VERSION
7# 5.9
8
9# Fish
10echo $FISH_VERSION
11# 3.7.0
12
13# Ksh
14echo $KSH_VERSION
15# Version AJM 93u+m/1.0.7

Detection Script

bash
1detect_shell() {
2    if [ -n "$BASH_VERSION" ]; then
3        echo "bash $BASH_VERSION"
4    elif [ -n "$ZSH_VERSION" ]; then
5        echo "zsh $ZSH_VERSION"
6    elif [ -n "$FISH_VERSION" ]; then
7        echo "fish $FISH_VERSION"
8    elif [ -n "$KSH_VERSION" ]; then
9        echo "ksh $KSH_VERSION"
10    else
11        echo "unknown: $(ps -p $$ -o comm=)"
12    fi
13}
14
15detect_shell

Checking Shell Features

bash
1# Check if the shell supports a specific feature
2# Arrays (bash/zsh, not sh/dash)
3if (eval 'arr=(1 2 3)') 2>/dev/null; then
4    echo "Shell supports arrays"
5fi
6
7# Check if running in POSIX mode
8if [ -n "$POSIXLY_CORRECT" ]; then
9    echo "Running in POSIX mode"
10fi

Methods on Different Systems

macOS

bash
1# Default shell (since macOS Catalina, it's zsh)
2dscl . -read /Users/$USER UserShell
3# UserShell: /bin/zsh
4
5# Current shell
6ps -p $$ -o comm=
7# zsh
8
9# Change default shell
10chsh -s /bin/bash

Linux

bash
1# Default shell from /etc/passwd
2grep $USER /etc/passwd | cut -d: -f7
3# /bin/bash
4
5# All available shells
6cat /etc/shells
7# /bin/sh
8# /bin/bash
9# /bin/zsh
10# /usr/bin/fish
11
12# Current shell
13ps -p $$ -o comm=

Within a Script

bash
1#!/bin/bash
2# Inside a script, $0 is the script name, not the shell
3echo $0         # ./myscript.sh
4echo $SHELL     # /bin/zsh (login shell, not the script's interpreter)
5
6# The shebang line determines which shell runs the script
7# Use /proc/self/exe on Linux to find the interpreter
8readlink /proc/$$/exe 2>/dev/null || ps -p $$ -o comm=

Login Shell vs Non-Login Shell

bash
1# Check if current shell is a login shell
2
3# Bash
4shopt -q login_shell && echo "login" || echo "non-login"
5
6# Zsh
7[[ -o login ]] && echo "login" || echo "non-login"
8
9# Generic — login shells have a leading dash in $0
10case "$0" in
11    -*) echo "login shell" ;;
12    *)  echo "non-login shell" ;;
13esac

Login shells read different config files:

  • bash login: ~/.bash_profile or ~/.profile
  • bash non-login: ~/.bashrc
  • zsh login: ~/.zprofile, ~/.zshrc
  • zsh non-login: ~/.zshrc

Common Pitfalls

  • Relying on $SHELL for the current shell: $SHELL is the default login shell, not the currently running shell. If you switched shells with bash or zsh, $SHELL still shows the original.
  • Assuming $0 always returns the shell name: Inside scripts, $0 is the script filename. In subshells, it may be -bash (with a leading dash) for login shells. Parse carefully.
  • Fish shell incompatibility: Fish does not support POSIX syntax ($?, $$, [ -n ]). Use echo $FISH_VERSION or status fish-path for detection in fish.
  • Confusing sh with bash: On many systems, /bin/sh is a symlink to bash or dash. Running sh may invoke bash in POSIX compatibility mode, which disables bash-specific features like arrays.
  • Not checking the shell before using shell-specific features: Bashisms like [[ ]], (( )), and arrays break in sh, dash, and other POSIX-only shells. Always check the shell or use POSIX-compatible syntax for portable scripts.

Summary

  • ps -p $$ -o comm= is the most reliable way to determine the current shell
  • $SHELL shows your default login shell, not the currently running shell
  • Shell-specific variables ($BASH_VERSION, $ZSH_VERSION, $FISH_VERSION) confirm both the shell and its version
  • $0 shows the shell name but includes a leading - for login shells and shows script names inside scripts
  • Always test for the current shell before using shell-specific features in portable scripts

Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.