Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux Shell 切換用戶:su 與 su - 的核心區別與最佳實踐

編輯:Linux 教學

在 Linux 運維與腳本編寫中,su 與 su -(或 su -l)的區別是導致「命令找不到」、「環境變量錯誤」、「工作目錄異常」等高頻問題的根源。本文通過原理分析、場景演示、腳本陷阱解析,助你徹底掌握用戶切換的正確姿勢。

一、 核心區別一覽

特性su usersu - user / su -l user
登錄 Shell 類型非登錄 Shell登錄 Shell
讀取配置文件僅 ~/.bashrc/etc/profile → ~/.bash_profile → ~/.bashrc
環境變量保留原用戶環境(PATH, HOME 等)重置為目標用戶完整環境
工作目錄保持原目錄不變切換至目標用戶 $HOME
適用場景臨時執行單條命令、保持上下文完整切換用戶身份、運行服務、執行腳本

二、 經典故障場景複現

場景 1:Oracle 用戶執行 sqlplus 報「command not found」

[root@db ~]# su oracle
[oracle@db ~]$ sqlplus / as sysdba
-bash: sqlplus: command not found
# 原因:保留了 root 的 PATH,未讀取 oracle 用戶 .bash_profile 中的 ORACLE_HOME/bin

修正:su - oracle

場景 2:腳本中切換用戶刪除文件失敗

# 錯誤寫法
su load <

三、 底層機制原理

  • su:調用 pam_authenticate() 驗證密碼 → setuid() 切換 UID/GID → execve("/bin/bash", ["-bash"], envp),**不清理環境變量**,argv[0] 為 -bash(非登錄 Shell 標誌)。
  • su -:同上,但 execve("/bin/bash", ["-bash", "-l"], envp) 傳遞 -l 參數,Bash 檢測到登錄 Shell 標誌,依次讀取 /etc/profile、~/.bash_profile、~/.bashrc,**重置 HOME、SHELL、USER、LOGNAME、PATH** 等關鍵變量。

四、 腳本自動化最佳實踐

1. 非交互式密碼傳遞(不推薦明文,僅演示)

# 使用 expect 或 sshpass
expect -c "
spawn su - load
expect \"Password:\"
send \"$PASSWD\r\"
expect \"\\$\"
send \"cd ~/backup && rm *.txt\r\"
send \"exit\r\"
expect eof
"

2. 推薦:sudo + 腳本分離

# /etc/sudoers.d/app-deploy
appuser ALL=(load) NOPASSWD: /opt/scripts/cleanup_backup.sh

# cleanup_backup.sh (屬於 load:load, 750)
#!/bin/bash
cd ~/backup
rm -f *.txt

# 執行
sudo -u load /opt/scripts/cleanup_backup.sh

3. systemd 服務單元(生產環境標準)

[Service]
User=load
Group=load
WorkingDirectory=/home/load/backup
ExecStart=/bin/rm -f *.txt
Type=oneshot

五、 總結口訣

「帶橫杠,換環境,回家目錄;不帶橫杠,留舊環境,原地待命。」

  • 運行服務、執行腳本、需要完整環境 → 永遠用 su - user。
  • 臨時查看文件、保持當前目錄上下文 → su user 可接受。
  • 自動化部署 → 棄用 su,改用 sudo、systemd、ssh、容器化方案。
Copyright © Windows教程網 All Rights Reserved