su (Substitute User) 是切換使用者身份的經典指令。許多人誤以為 su - 只是「帶環境變數切換」,實際上它涉及 **進程樹結構、Real UID / Effective UID 分離、Shell 父子關係**。本文透過進程視角深度剖析 su 運作機制,並釐清 whoami 與 who am i 的本質差異。
su 二進制檔擁有 **Setuid 位 (rwsr-xr-x)**,執行時 EUID 變為目標使用者 (通常 root=0),RUID 不變。# 原始狀態:root 登入,PID 2939 (bash)
root@host:~# ps -o pid,ppid,cmd
PID PPID CMD
2939 2935 bash
# su - yunhw
yunhw@host:~$ ps -o pid,ppid,cmd
PID PPID CMD
2939 2935 bash # root 原本的 shell (父進程)
2958 2939 su - yunhw # su 進程
2966 2958 -su # yunhw 的新 login shell (子進程)
# who am i 顯示 RUID (登入者) → root
# whoami 顯示 EUID (當前權限) → yunhw
結論:su **不會結束原使用者的 Shell**,只是在其下 fork 新 Shell。輸入 exit 或 Ctrl+D 只會結束子 Shell,返回父 Shell。若殺死父進程 (kill -9 2939),整個終端機登出。
| 指令 | 環境變數 | 工作目錄 | Shell 類型 | 適用場景 |
|---|---|---|---|---|
su user | 保留呼叫者環境 | 不變 | 非登入 Shell | 臨時以該身份執行單一指令 |
su - usersu -l user | 重置為目標使用者完整環境 | 切換至目標家目錄 | 登入 Shell (讀取 /etc/profile, ~/.bash_profile) | 完整切換身份、執行該使用者慣用環境 |