su 指令:su 與 su - 的差異、sudo su 與 sudo -i,以及切換帳號的方法

測試環境RHEL 系列AlmaLinux 9.8util-linux 2.37root 帳號Debian 12 · util-linux 2.38 一般帳號2026-11-05 確認
使用者 · 群組指令su位置/usr/bin/su
用其他帳號執行指令

在 Linux 上不登出目前的帳號、改用其他帳號執行指令時,就使用 su 指令。在 AlmaLinux 9 伺服器上從 root 帳號對無法登入的系統帳號 daemon 執行 su 並比較的結果,一個連字號就讓工作資料夾和 PATH 改變,而且要指定 shell 指令才會執行。

下面的輸出是在 AlmaLinux 9.8 伺服器(root 帳號)和 Debian 12 伺服器(一般帳號)上執行的結果。詢問密碼的畫面和 sudo 沒有在正式運作的伺服器上執行,而是依官方手冊整理;PATH 值的一部分和模擬器中 util-linux 的修補版本號碼已換成範例值。

1️⃣ su 指令的用法

  • ↪️ 基本格式與用 exit 返回

基本格式是 [su 帳號名稱],省略帳號名稱時會切換成 root。在新的 shell 輸入 exit,那個 shell 就會結束,回到執行 su 的原本帳號的 shell。

從一般帳號執行時,要在 Password: 那一行輸入要切換的帳號的密碼(依 PAM 預設設定)。這台伺服器的 /etc/pam.d/su 設定成執行者是 root 時略過驗證,所以從 root 帳號切換到 daemon 時沒有詢問密碼。

su --help

Usage:
 su [options] [-] [<user> [<argument>...]]

Change the effective user ID and group ID to that of <user>.
A mere - implies -l.  If <user> is not given, root is assumed.

Options:
 -m, -p, --preserve-environment      do not reset environment variables
 -w, --whitelist-environment <list>  don't reset specified variables

 -g, --group <group>             specify the primary group
 -G, --supp-group <group>        specify a supplemental group

 -, -l, --login                  make the shell a login shell
 -c, --command <command>         pass a single command to the shell with -c
 --session-command <command>     pass a single command to the shell with -c
                                   and do not create a new session
 -f, --fast                      pass -f to the shell (for csh or tcsh)
 -s, --shell <shell>             run <shell> if /etc/shells allows it
 -P, --pty                       create a new pseudo-terminal

 -h, --help                      display this help
 -V, --version                   display version

For more details see su(1).

如說明所寫,連字號 [-] 是與 [-l] 相同的登入選項,寫在帳號名稱後面的引數會交給切換後帳號的 shell。AlmaLinux 9 伺服器的 su 來自 util-linux 2.37 套件,Debian 12 伺服器的 su 來自 2.38 套件。

su --version
su from util-linux 2.38.1

想切換的帳號能不能開啟 shell,看 getent passwd 中該帳號那一行的最後一欄就知道。

getent passwd daemon
daemon:x:2:2:daemon:/sbin:/sbin/nologin

daemon 的 shell 是 /sbin/nologin。登入用 shell 的位置寫著 nologin 的帳號,即使用 su 切換過去也不會開啟 shell。

2️⃣ su 與 su - 的差異

  • ↪️ 登入 shell 與環境變數

加上連字號(-)時,su 會開啟和用切換後帳號登入時相同的 shell。在 /tmp 資料夾裡,同一個指令不加連字號執行一次,加上連字號再執行一次。

su -s /bin/sh -c pwd daemon
/tmp
su - -s /bin/sh -c pwd daemon
/usr/sbin

沒有連字號時工作資料夾仍是 /tmp,[su -] 則移到 daemon 的家目錄 /sbin。這台伺服器的 /sbin 是連到 /usr/sbin 的連結,所以 pwd 顯示 /usr/sbin。

環境變數只從 env 的輸出中挑出 HOME、USER、SHELL、PATH、LOGNAME 五行來比較。

su -s /bin/sh -c env daemon | grep -E '^(HOME|USER|SHELL|PATH|LOGNAME)='
SHELL=/bin/sh
LOGNAME=daemon
HOME=/sbin
USER=daemon
PATH=/root/.local/bin:/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
su - -s /bin/sh -c env daemon | grep -E '^(HOME|USER|SHELL|PATH|LOGNAME)='
SHELL=/bin/sh
LOGNAME=daemon
HOME=/sbin
USER=daemon
PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin

HOME、USER、LOGNAME 在兩種情況下都變成 daemon 的值。PATH 在沒有連字號時保留執行 su 的 root 的值,[su -] 則依登入設定重新決定。

依官方手冊,沒有連字號的 su 只改變 HOME 和 SHELL,只有在目標帳號不是 root 時才連 USER 和 LOGNAME 一起改變。因此從一般帳號不加連字號切換成 root 時,USER 會留著原本的帳號名稱。

顯示 shell 名稱的 [$0] 也不一樣。

su -s /bin/sh -c 'echo $0' daemon
sh
su - -s /bin/sh -c 'echo $0' daemon
-sh

[su -] 的 shell 名稱前面加上了連字號,顯示為 -sh。名稱以連字號開頭的 shell 會以登入 shell 運作,並讀取登入設定檔(依官方手冊)。兩種形式的差異如下。

比較susu -
工作資料夾不變(/tmp)切換後帳號的家目錄(/usr/sbin)
HOME, USER, LOGNAMEdaemon 的值daemon 的值
PATH執行 su 的 root 的值依登入設定重新決定
shell 名稱($0)sh-sh(登入 shell)
其他環境變數保持原樣只留下 TERM 等一部分,其餘清除(依官方手冊)

官方手冊建議一律加上登入選項以免環境混在一起,並以 [--login] 代替連字號。沒有連字號的 su 會保留目前的資料夾和 PATH,所以想用其他帳號的設定確認指令時,結果可能和 [su -] 不同。

3️⃣ su -c 與 su -s 選項

  • ↪️ 只執行一個指令與指定 shell

不開啟 shell、只用其他帳號執行一個指令時,在 -c 後面寫上指令。對 nologin 帳號用 [su -c] 執行 id,出現的是拒絕訊息而不是指令結果。

su -c id daemon
This account is currently not available.

用 -c 傳入的指令也是由帳號的 shell 接收並執行,所以 shell 是 nologin 時指令根本不會被執行。這時用 -s 指定要執行的 shell。

su -s /bin/sh -c id daemon
uid=2(daemon) gid=2(daemon) groups=2(daemon)

指定 /bin/sh 後,id 以 daemon 的 UID 2 執行。要用服務帳號確認檔案權限或指令結果時,就使用這個形式。

如果目標帳號的 shell 是像 nologin 這樣不在 /etc/shells 裡的受限 shell,只有 root 能用 -s 換 shell。依官方手冊,這時非 root 使用者指定的 -s 和 SHELL 變數會被忽略。

-c 後面的指令有空格時,用引號括起來當成一整塊傳入。su 會原樣傳回所執行指令的結束代碼,無法執行指令時傳回 126,找不到指令時傳回 127(依官方手冊)。

📌 主要選項:本文實際執行的結果

選項作用本文看到的結果
-開啟和用目標帳號登入時相同的 shell,並移到該帳號的家目錄在 /tmp 不加連字號時 pwd 是 /tmp,加上後是 /usr/sbin,echo $0 為 -sh
-c 指令不開啟 shell,用目標帳號的 shell 執行一個指令對 nologin 帳號 daemon 執行 su -c id daemon,出現 [This account is currently not available.]
-s shell用指定的 shell 代替帳號設定的 shell 執行,受限 shell 帳號只限 rootsu -s /bin/sh -c id daemon 得到 uid=2(daemon) gid=2(daemon) groups=2(daemon)
--help顯示用法與選項清單Usage 行與 -m、-w、-g、-G、-l、-c、-f、-s、-P、-h、-V 選項清單
--version輸出版本資訊Debian 12 伺服器上為 su from util-linux 2.38.1

📎 其他選項:依官方手冊

選項作用
-l與連字號(-)相同的登入選項,長名稱為 --login
-m保留環境變數,也不改變 HOME、SHELL、USER、LOGNAME,與登入選項一起使用時會被忽略(同 -p)
-w 清單登入選項清空環境時保留以逗號列出的變數,HOME、SHELL、USER、LOGNAME、PATH 會重新決定
-g 群組指定主要群組,只限 root
-G 群組指定補充群組,只限 root,沒有 -g 時第一個補充群組就是主要群組
-f把 -f 傳給 shell,是 csh 或 tcsh 使用的選項
-P建立新的虛擬終端機,不與原本的工作階段共用終端機
--session-command 指令與 -c 相同但不建立新的工作階段,手冊不建議使用

🔲 su 指令模擬器

下面的模擬器從一般帳號 user1 開始,可以自己輸入 su、[su -]、sudo,再用 exit 返回,親自確認整個流程。帳號和密碼都是範例值。

su 指令模擬器util-linux 2.37
[user1@server1 ~]$
只在瀏覽器裡運作,帳號和密碼都是範例值,用 ↑↓ 可以叫出前面用過的指令(密碼不會留在紀錄中)。

4️⃣ sudo su 與 sudo -i 的差異

  • ↪️ 詢問的密碼與改變的資料夾

sudo su 是用 sudo 以 root 權限執行 su 的形式。因為 su 由 root 執行,所以不會詢問 root 密碼,而是在那之前由 sudo 詢問執行者的密碼(依官方文件)。

可以執行 sudo 的帳號由 /etc/sudoers 設定決定。未獲允許的帳號執行 sudo 時,會以 [user1 is not in the sudoers file.] 拒絕(依程式內的訊息)。

開啟 root shell 的各個指令所詢問的密碼與工作資料夾如下。本章的指令沒有在正式運作的伺服器上執行,而是依 su(1) 與 sudo(8) 手冊整理。

指令詢問的密碼執行的 shell工作資料夾
surootroot shell不變
su -rootroot 登入 shell/root
sudo su執行的帳號root shell不變
sudo su -執行的帳號root 登入 shell/root
sudo -i執行的帳號root 登入 shell/root
sudo -s執行的帳號SHELL 變數的 shell(root 權限)不變

[sudo -i] 和 [sudo su -] 最後都會成為 root 登入 shell。[sudo -i] 由 sudo 直接把 root 的 shell 當成登入 shell 執行,[sudo su -] 則在中間再經過一次 su。

[sudo -s] 以 root 權限執行 SHELL 變數的 shell,不會移到家目錄。sudo 在密碼正確輸入一次後,預設 5 分鐘內在同一個終端機不會再詢問(依 sudoers 手冊)。

su 與 sudo 的差異,就像借用別人家的鑰匙和在管理室登記名字後進出的差異。

5️⃣ su 指令錯誤

  • ↪️ This account is currently not available · Authentication failure

切換到無法登入的帳號時,會以 nologin 代替 shell 執行,並出現 [This account is currently not available.]。在 root 執行 [su daemon] 時只出現這一行,結束代碼為 1。

su daemon
This account is currently not available.

這段訊息由寫在帳號那一行最後一欄的 nologin 程式輸出,也在伺服器的 /usr/sbin/nologin 中找到了相同的文字。如果是 root,可以用 -s 指定 shell,再以該帳號執行指令。

密碼不對時會出現 [su: Authentication failure]。這段文字是 PAM 函式庫在驗證失敗時傳回的訊息。依官方手冊,su 在執行指令前失敗時,結束代碼為 1。

明明正確輸入了自己帳號的密碼 su 卻拒絕時,先確認那裡要輸入的是不是目標帳號的密碼。因為 sudo 詢問的是執行者的密碼,su 詢問的則是要切換過去的帳號的密碼。

寫了不存在的帳號名稱時,會出現 [su: user user9 does not exist or the user entry does not contain all the required fields](依程式內的訊息)。各錯誤的原因與要確認的事項如下。

輸出原因要確認的事項
This account is currently not available.目標帳號的 shell 是 nologingetent passwd 帳號那一行的最後一欄、root 可用 -s 指定 shell
su: Authentication failure密碼不對是不是目標帳號的密碼(sudo 是你自己的密碼)
su: user user9 does not exist …沒有這個名稱的帳號getent passwd 帳號名稱
user1 is not in the sudoers file.未允許使用 sudo 的帳號sudoers 設定與 wheel 群組

🔢 FAQ & 推薦內容

官方手冊把 su 主要說明為給一般使用者用的指令,並建議 root 執行的腳本使用不經過驗證的 runuser 指令。格式是 [runuser -u 帳號 -- 指令]。

在 -w(--whitelist-environment)後面用逗號連接寫出要保留的變數名稱,[su -] 清空環境時就會保留那些變數。依官方手冊,HOME、SHELL、USER、LOGNAME、PATH 即使在清單中也會重新決定。

依官方手冊,su 一律把失敗的登入嘗試記錄在 btmp 檔案,不寫入 lastlog 檔案。btmp 的紀錄可用 lastb 指令查看。

ℹ️ 聯盟行銷說明
本站內容包含聯盟行銷連結。訪客透過這些連結購買商品或服務時,本站會從賣家獲得佣金。在這個過程中,購買者支付的金額(遇到活動折扣時金額會降低↓)並不會因此提高。刊登的價格、折扣與庫存資訊以撰寫當時為準,可能與實際情況不同,購買前請向賣家做最後確認。商品的挑選與評價依本站自訂的標準撰寫,是否支付佣金不會影響介紹順序或評價內容。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Prove your humanity: 0   +   5   =