「我現在用的是 bash 還是 zsh?」「腳本裡怎麼判斷當前 Shell?」本文總結 7 種查看當前 Shell 的方法,對比它們的準確度、適用場景與局限性,並給出「一條指令搞定」的最佳實踐。

/etc/profile、~/.bash_profile 等ssh cmd$SHELL 可能不反映「當前實際運行」的 Shell| # | 方法 | 指令 | 輸出範例 | 準確度 | 說明 |
|---|---|---|---|---|---|
| 1 | 環境變數 $SHELL | echo $SHELL | /bin/bash | ⭐⭐ | 登入 Shell,不隨切換變化 (如 exec zsh 後仍顯示 bash) |
| 2 | 特殊參數 $0 | echo $0 | -bash 或 /bin/zsh | ⭐⭐⭐ | 當前 Shell 進程名,但非所有 Shell 支援 (如 dash 某版本) |
| 3 | 環境變數 grep | env | grep SHELL | SHELL=/bin/bash | ⭐⭐ | 同 $SHELL,僅顯示登入 Shell |
| 4 | /etc/passwd 查帳號 | grep ^$USER: /etc/passwd | user:x:1000:1000::/home/user:/bin/bash | ⭐⭐ | 用戶預設登入 Shell,非當前 Shell |
| 5 | ps 查看當前進程 | ps -p $$ | PID TTY TIME CMD\n1234 pts/0 00:00:00 bash | ⭐⭐⭐⭐ | 直接看 PID=$$ (當前 Shell 進程) 的 CMD 欄,最準確 |
| 6 | echo $$ 再 grep | ps -ef | grep $$ | 同上 | ⭐⭐⭐ | 需過濾 grep 自身,較繁瑣 |
| 7 | 輸入錯誤指令看報錯 | asdf | bash: asdf: command not found | ⭐ | 僅能推斷互動 Shell,腳本中無效 |
ps -p $$ -o comm=
# 輸出:bash / zsh / fish / dash ...
-p $$:指定當前 Shell 進程 ID-o comm=:只輸出指令名 (無標頭)#!/bin/sh
CURRENT_SHELL=$(ps -p $$ -o comm=)
case "$CURRENT_SHELL" in
bash) echo "Running in Bash, 可用陣列、[[ ]]";;
zsh) echo "Running in Zsh, 可用擴展通配符";;
dash) echo "Running in Dash, 嚴格 POSIX";;
*) echo "Running in $CURRENT_SHELL";;
esac
cat /etc/shells
# /bin/sh
# /bin/bash
# /bin/zsh
# /usr/bin/fish
# /sbin/nologin
chsh -s /bin/zsh:永久更改登入 Shellexec zsh:當前會話臨時切換 (不影響 $SHELL)echo $0 最快ps -p $$ -o comm= 最準確grep ^$USER: /etc/passwd 或 getent passwd $USER$SHELL、/etc/passwd 不會變,僅 $0、ps 反映新 Shell掌握這 7 種方法的差異,下次遇到「為什麼腳本行為不符預期?」時,先查 ps -p $$ -o comm= 確認執行環境,即可快速定位 Shebang 或語法相容性問題。