面試被問 Linux 命令 su 和 sudo 的區別?

2022-01-27 終碼一生

點擊「終碼一生」,關注,置頂公眾號

每日技術乾貨,第一時間送達!

之前一直對 su 和 sudo 這兩個命令犯迷糊,最近專門搜了這方面的資料,總算是把兩者的關係以及用法搞清楚了,這篇文章來系統總結一下。

 

因為本篇博客中涉及到用戶切換,所以我需要提前準備好幾個測試用戶,方便後續切換。

Linux 中新建用戶的命令是 useradd ,一般系統中這個命令對應的路徑都在 PATH 環境變量裡,如果直接輸入 useradd 不管用的話,就用絕對路徑名的方式:/usr/sbin/useradd 。

useradd 新建用戶命令只有 root 用戶才能執行,我們先從普通用戶 ubuntu 切換到 root 用戶(如何切換後文會介紹):

ubuntu@VM-0-14-ubuntu:~$ su -  
Password: # 輸入 root 用戶登錄密碼  
root@VM-0-14-ubuntu:~# useradd -m test_user # 帶上 -m 參數  
root@VM-0-14-ubuntu:~# ls /home  
test_user  ubuntu  # 可以看到 /home 目錄下面有兩個用戶了  

因為還沒有給新建的用戶 test_user 設置登錄密碼,這就導致我們無法從普通用戶 ubuntu 切換到 test_user,所以接下來,我們需要用 root 來設置 test_user 的登錄密碼。需要用到 passwd 命令:

root@VM-0-14-ubuntu:~# passwd test_user  
Enter new UNIX password:  # 輸出 test_user 的密碼  
Retype new UNIX password:         
passwd: password updated successfully  
root@VM-0-14-ubuntu:~#  

接著我們輸入 exit 退出 root 用戶到 普通用戶 ubuntu:

root@VM-0-14-ubuntu:~# exit  
logout  
ubuntu@VM-0-14-ubuntu:~$  

可以看到,命令提示符前面已經由 root 變成 ubuntu,說明我們現在的身份是 ubuntu 用戶。

 

首先需要解釋下 su 代表什麼意思。

之前一直以為 su 是 super user,查閱資料之後才知道原來表示 switch user。

知道 su 是由什麼縮寫來的之後,那麼它提供的功能就顯而易見了,就是切換用戶

2.1 - 參數

su 的一般使用方法是:

su  <user_name>  

或者

su - <user_name>  

兩種方法只差了一個字符 -,會有比較大的差異:

如果加入了 - 參數,那麼是一種 login-shell 的方式,意思是說切換到另一個用戶 <user_name> 之後,當前的 shell 會加載 <user_name> 對應的環境變量和各種設置;如果沒有加入 - 參數,那麼是一種 non-login-shell 的方式,意思是說我現在切換到了 <user_name>,但是當前的 shell 還是加載切換之前的那個用戶的環境變量以及各種設置。

光解釋會比較抽象,我們看一個例子就比較容易理解了。

我們首先從 ubuntu 用戶以 non-login-shell 的方式切換到 root 用戶,比較兩種用戶狀態下環境變量中 PWD 的值(su 命令不跟任何 <user_name> ,默認切換到 root 用戶):

ubuntu@VM-0-14-ubuntu:~$ env | grep ubuntu  
USER=ubuntu  
PWD=/home/ubuntu    # 是 /home/ubuntu  
HOME=/home/ubuntu  
# 省略.  
ubuntu@VM-0-14-ubuntu:~$ su    # non-login-shell 方式  
Password:     # 輸入 root 用戶登錄密碼  
root@VM-0-14-ubuntu:/home/ubuntu# env | grep ubuntu  
PWD=/home/ubuntu  # 可以發現還是 /home/ubuntu  
root@VM-0-14-ubuntu:/home/ubuntu#  

我們的確是切換到 root 用戶了,但是 shell 環境中的變量並沒有改變,還是用之前 ubuntu 用戶的環境變量。

接著我們從 ubuntu 用戶以 login-shell 的方式切換到 root 用戶,同樣比較兩種用戶轉臺下環境變量中 PWD 的值:

ubuntu@VM-0-14-ubuntu:~$ env | grep ubuntu  
USER=ubuntu  
PWD=/home/ubuntu  # 是 /home/ubuntu  
HOME=/home/ubuntu  
# 省略..  
ubuntu@VM-0-14-ubuntu:~$ su -   # 是 login-shell 方式  
Password:  
root@VM-0-14-ubuntu:~# env | grep root  
USER=root  
PWD=/root   # 已經變成 /root 了  
HOME=/root  
MAIL=/var/mail/root  
LOGNAME=root  
root@VM-0-14-ubuntu:~#  

可以看到用 login-shell 的方式切換用戶的話,shell 中的環境變量也跟著改變了。

總結:具體使用哪種方式切換用戶看個人需求:

如果不想因為切換到另一個用戶導致自己在當前用戶下的設置不可用,那麼用 non-login-shell 的方式;如果切換用戶後,需要用到該用戶的各種環境變量(不同用戶的環境變量設置一般是不同的),那麼使用 login-shell 的方式。2.2 切換到指定用戶

前面已經介紹了,如果 su 命令後面不跟任何 <user_name>,那麼默認是切換到 root 用戶:

ubuntu@VM-0-14-ubuntu:~$ su -  
Password:  # root 用戶的密碼  
root@VM-0-14-ubuntu:/home/ubuntu#  

因為我們在 1. 準備工作部分已經新建了一個 test_user 用戶,並且我們也知道 test_user 用戶的登錄密碼(root 用戶設置的),我們就能從 ubuntu 用戶切換到 test_user 用戶:

ubuntu@VM-0-14-ubuntu:~$ su - test_user  
Password:   # test_user 用戶的密碼  
$  

2.3 -c 參數

前面的方法中,我們都是先切換到另一個用戶(root 或者 test_user),在哪個用戶的狀態下執行命令,最後輸入 exit 返回當前 ubuntu 用戶。

還有一種方式是:不需要先切換用戶再執行命令,可以直接在當前用戶下,以另一個用戶的方式執行命令,執行結束後就返回當前用戶。這就得用到 -c 參數。

具體使用方法是:

su - -c "指令串"  # 以 root 的方式執行 "指令串"  

我麼看個例子:

ubuntu@VM-0-14-ubuntu:~$ cat /etc/shadow  
cat: /etc/shadow: Permission denied    # ubuntu 用戶不能直接查看 /etc/shadow 文件內容  
ubuntu@VM-0-14-ubuntu:~$ su - -c "tail -n 4 /etc/shadow"  
Password:  # 輸入 root 用戶密碼  
ubuntu:$1$fZKcWEDI$uwZ64uFvVbwpHTbCSgim0/:18352:0:99999:7:::  
ntp:*:17752:0:99999:7:::  
mysql:!:18376:0:99999:7:::  
test_user:$6$.ZY1lj4m$ii0x9CG8h.JHlh6zKbfBXRuolJmIDBHAd5eqhvW7lbUQXTRS//89jcuTzRilKqRkP8YbYW4VPxmTVHWRLYNGS/:18406:0:99999:7:::  
ubuntu@VM-0-14-ubuntu:~$   # 執行完馬上返回 ubuntu 用戶而不是 root 用戶  

這種執行方式和後面要介紹的 sudo 很像,都是臨時申請一下 root 用戶的權限。但還是有差異,我們接著往後看。

 

首先還是解釋下 sudo 命令是什麼意思。

sudo 的英文全稱是 super user do,即以超級用戶(root 用戶)的方式執行命令。這裡的 sudo 和之前 su 表示的 switch user 是不同的,這點需要注意,很容易搞混。

我們先介紹 sudo 命令能做什麼事情,然後說明為何能做到這些,以及如何做到這些。

我們開始。

3.1 主要用法

我們在 Linux 中經常會碰到 Permission denied 這種情況,比如以 ubuntu 用戶的身份查看 /etc/shadow 的內容。因為這個文件的內容是只有 root 用戶能查看的。

那如果我們想要查看怎麼辦呢?這時候就可以使用 sudo :

ubuntu@VM-0-14-ubuntu:~$ tail -n 3 /etc/shadow  
tail: cannot open '/etc/shadow' for reading: Permission denied      # 沒有權限  
ubuntu@VM-0-14-ubuntu:~$ sudo !!                                    # 跟兩個驚嘆號  
sudo tail -n 3 /etc/shadow  
ntp:*:17752:0:99999:7:::  
mysql:!:18376:0:99999:7:::  
test_user:$6$.ZY1lj4m$ii0x9CG8h.JHlh6zKbfBXRuolJmIDBHAd5eqhvW7lbUQXTRS//89jcuTzRilKqRkP8YbYW4VPxmTVHWRLYNGS/:18406:0:99999:7:::  
ubuntu@VM-0-14-ubuntu:~$  

實例中,我們使用了 sudo !! 這個小技巧,表示重複上面輸入的命令,只不過在命令最前面加上 sudo 。

因為我已經設置了 sudo 命令不需要輸入密碼,所以這裡 sudo !! 就能直接輸出內容。如果沒有設置的話,需要輸入當前這個用戶的密碼,例如本例中,我就應該輸入 ubuntu 用戶的登錄密碼。

兩次相鄰的 sudo 操作,如果間隔在 5min 之內,第二次輸入 sudo 不需要重新輸入密碼;如果超過 5min,那麼再輸入 sudo 時,又需要輸入密碼。所以一個比較省事的方法是設置 sudo 操作不需要密碼。後面介紹如何設置。

sudo 除了以 root 用戶的權限執行命令外,還有其它幾個用法,這裡做簡單介紹。

切換到 root 用戶:

sudo su -  

這種方式也能以 login-shell 的方式切換到 root 用戶,但是它和 su - 方法是由區別的:

前者輸入 sudo su - 後,需要提供當前用戶的登錄密碼,也就是 ubuntu 用戶的密碼;後者輸入 su - 後,需要提供 root 用戶的登錄密碼。

還有一個命令:

sudo -i  

這個命令和 sudo su - 效果一致,也是切換到 root 用戶,也是需要提供當前用戶(ubuntu 用戶)的登錄密碼。

我們現在切換到 test_user 用戶,嘗試顯示 /etc/shadow 文件的內容:

ubuntu@VM-0-14-ubuntu:~$ su - test_user  
Password:   # test_user 的密碼  
$ sudo cat /etc/shadow  
[sudo] password for test_user: # test_user 的密碼  
test_user is not in the sudoers file.  This incident will be reported.  
$  

我們會看到倒數第二行中的錯誤提示信息,我們無法查看 /etc/shadow 的內容,這是為什麼?為什麼 ubuntu 可以使用 sudo 但是 test_user 不行呢?

這就涉及到 sudo 的工作原理了。

3.2 sudo 工作原理

一個用戶能否使用 sudo 命令,取決於 /etc/sudoers 文件的設置。

從 3.1 節中我們已經看到,ubuntu 用戶可以正常使用 sudo ,但是 test_user 用戶卻無法使用,這是因為 /etc/sudoers 文件裡沒有配置 test_user。

/etc/sudoers 也是一個文本文件,但是因其有特定的語法,我們不要直接用 vim 或者 vi 來編輯它,需要用 visudo 這個命令。輸入這個命令之後就能直接編輯 /etc/sudoers 這個文件了。

需要說明的是,只有 root 用戶有權限使用 visudo 命令。

我們先來看下輸入 visudo 命令後顯示的內容。

輸入(root 用戶):

root@VM-0-14-ubuntu:~# visudo  

輸出:

# User privilege specification  
root    ALL=(ALL:ALL) ALL  
  
# Members of the admin group may gain root privileges  
%admin ALL=(ALL) ALL  
  
# Allow members of group sudo to execute any command  
%sudo   ALL=(ALL:ALL) ALL  
  
# See sudoers(5) for more information on "#include" directives:  
  
#includedir /etc/sudoers.d  
ubuntu  ALL=(ALL:ALL) NOPASSWD: ALL  

解釋下每一行的格式:

第一個表示用戶名,如 root 、ubuntu 等;接下來等號左邊的 ALL 表示允許從任何主機登錄當前的用戶帳戶;等號右邊的 ALL 表示:這一行行首對一個的用戶可以切換到系統中任何一個其它用戶;行尾的 ALL 表示:當前行首的用戶,能以 root 用戶的身份下達什麼命令,ALL 表示可以下達任何命令。

我們還注意到 ubuntu 對應的那一行有個 NOPASSWD 關鍵字,這就是表明 ubuntu 這個用戶在請求 sudo 時不需要輸入密碼,到這裡就解釋了前面的問題。

同時我們注意到,這個文件裡並沒有 test_user 對應的行,這也就解釋了為什麼 test_user 無法使用 sudo 命令。

接下來,我們嘗試將 test_user 添加到 /etc/sudoers 文件中,使 test_user 也能使用 sudo 命令。我們在最後一行添加:

test_user  ALL=(ALL:ALL)  ALL   # test_user 使用 sudo 需要提供 test_user 的密碼  

接下來我們再在 test_user 帳戶下執行 sudo :

ubuntu@VM-0-14-ubuntu:~$ su - test_user  
Password:  
$ tail -n 3 /etc/shadow  
tail: cannot open '/etc/shadow' for reading: Permission denied  
$ sudo tail -n 3 /etc/shadow                   # 加上 sudo  
ntp:*:17752:0:99999:7:::  
mysql:!:18376:0:99999:7:::  
test_user:$6$.ZY1lj4m$ii0x9CG8h.JHlh6zKbfBXRuolJmIDBHAd5eqhvW7lbUQXTRS//89jcuTzRilKqRkP8YbYW4VPxmTVHWRLYNGS/:18406:0:99999:7:::  
$  

可以看到,現在已經可以使用 sudo 了。

3.3 思考

我們已經看到了,如果一個用戶在 /etc/sudoers 文件中,那麼它就具有 sudo 權限,就能通過 sudo su - 或者 sudo -i 等命令切換到 root 用戶了,那這時這個用戶就變成 root 用戶了,那這不對系統造成很大的威脅嗎?

實際上的確是這樣的。所以如果在編輯 /etc/sudoers 文件賦予某種用戶 sudo 權限時,必須要確定該用戶是可信任的,不會對系統造成惡意破壞,否則將所有 root 權限都賦予該用戶將會有非常大的危險。

當然,root 用戶也可以編輯 /etc/sudoers 使用戶只具備一部分權限,即只能執行一小部分命令。有興趣的讀者可以參考 Reference 部分第二條,這篇文章不再贅述。

 

 

我們已經看到:

使用 su - ,提供 root 帳戶的密碼,可以切換到 root 用戶;使用 sudo su - ,提供當前用戶的密碼,也可以切換到 root 用戶

兩種方式的差異也顯而易見:如果我們的 Linux 系統有很多用戶需要使用的話,前者要求所有用戶都知道 root 用戶的密碼,這顯然是非常危險的;後者是不需要暴露 root 帳戶密碼的,用戶只需要輸入自己的帳戶密碼就可以,而且哪些用戶可以切換到 root,這完全是受 root 控制的(root 通過設置 /etc/sudoers 實現的),這樣系統就安全很多了。

相關焦點

  • 面試:說說Linux 命令 su 和 sudo 的區別?
    3. sudo 命令介紹及主要用法首先還是解釋下 sudo 命令是什麼意思。sudo 的英文全稱是 super user do,即以超級用戶(root 用戶)的方式執行命令。這裡的 sudo 和之前 su 表示的 switch user 是不同的,這點需要注意,很容易搞混。我們先介紹 sudo 命令能做什麼事情,然後說明為何能做到這些,以及如何做到這些。
  • Linux 命令 su 和 sudo 的區別?
    之前一直對 su 和 sudo 這兩個命令犯迷糊,最近專門搜了這方面的資料,總算是把兩者的關係以及用法搞清楚了,這篇文章來系統總結一下。因為本篇博客中涉及到用戶切換,所以我需要提前準備好幾個測試用戶,方便後續切換。
  • Linux運維基礎 - su 和 sudo 命令
    1.su 命令1.1 命令簡介su 用於臨時切換身份到另一個指定的用戶,未指定用戶名默認為 root。使用 su 切換用戶身份後,默認情況下不改變當前工作目錄,但會改變 HOME、SHELL、USER、LOGNAME 等 Shell 的環境變量。1.2 命令格式su [OPTIONS] [-] [USER [ARG...]]
  • 深入理解 sudo 與 su 之間的區別
    本文,我們將詳細討論關於 su 命令與 sudo 命令之間的區別。在開始之前有必要說明一下,文中所涉及到的示例教程都已經在 Ubuntu 14.04 LTS 上測試通過。Linux su 命令su 命令的主要作用是讓你可以在已登錄的會話中切換到另外一個用戶。換句話說,這個工具可以讓你在不登出當前用戶的情況下登錄為另外一個用戶。
  • Linux su命令的使用案例
    前言本文主要是講解與演示Linux系統中的su命令的使用與常見用法。Linux su命令的使用案例su命令也稱為switch user,翻譯為切換用戶。該命令用於在登錄會話期間把用戶身份切換到其他用戶。當沒有指定切換目標用戶名時,su默認切換到root用戶。正常來說,su命令用於在不退出系統的情況下將當前登錄的用戶切換到另一個用戶。
  • 每天一個Linux命令(28):sudo
    ALL是指目標用戶,也就是以誰的身份去執行命令,最後一個ALL當然就是指命令名了例如指明aaaa用戶,可以以root命令執行創建用戶的命令aaaa ALL=(root) /usr/sbin/useradd用法:sudo -h | -K | -k | -Vsudo -v [-AknS] [-g group] [-
  • linux常用命令用法匯總
    12 ll命令 13 netstat 14 kill命令 15 set命令 16 su命令 Reference1 find命令1.1 find命令中:find -regex 與find -name的區別 若一個目錄中,有如下目錄:susu@ubuntu:~/find_test$ lsaaa aaa 22 1
  • Linux中設置'sudo'的10個小技巧
    在Linux和其他類Unix作業系統中,只有root用戶可以運行所有命令並在系統上執行某些關鍵操作,如安裝和更新,刪除包,創建用戶和組,修改重要的系統配置文件等。然而,承擔root用戶角色的系統管理員可以允許其他正常系統用戶在sudo命令和幾個配置的幫助下運行某些命令以及執行包括上述的一些重要系統操作。
  • linux系統管理指令Sudo出現重大漏洞!影響絕大多數Linux系統
    sudo是linux系統管理指令,是允許系統管理員讓普通用戶執行一些或者全部的root命令的一個工具,如halt,reboot,su
  • 使用 pam 幫我們記錄su | sudo密碼
    作者:Evi1oXCentos(Redhat)使用 vim
  • Linux 新手必知必會的 10 條 Linux 基本命令
    1. sudo這條命令的意思是「以超級用戶的身份執行」,是 SuperUserDo 的簡寫,它是新手將要用到的最重要的一條 Linux 命令。當一條單行命令需要 root 權限的時候,sudo命令就派上用場了。你可以在每一條需要 root 權限的命令前都加上sudo。
  • 每天都在敲的sudo命令,你真的了解嗎
    雖然 sudo 無疑是在 Linux 中使用命令行的任何人都必須知道的命令,但為了更負責任和有效地使用該命令,您還應該了解其他幾個相關(和深入)的細節。這正是我們將在本文中討論的內容。大家可能會問,為啥我沒有給我的linux用戶授權,照樣也能使用sudo?這是因為你這個用戶肯定是在安裝系統的時候創建的,系統已經幫你添加了sudo授權。你可以試下使用useradd命令創建用戶,這些用戶默認沒有sudo權限。
  • linux之sudo使用技巧匯總
    sudo和su之間的區別sudo用於普通用戶可以使用root權限來執行命令su命令是當前用戶用來切換到另外一個用戶的命令,參數為用戶名。執行時會要求輸入密碼,這個密碼是你要切換到的用戶的密碼。sudo 表示 「superuser do」。它允許已驗證的用戶以其他用戶的身份來運行命令。其他用戶可以是普通用戶或者超級用戶。
  • Linux 之 sudo 命令
    Linux sudo命令Linux sudo命令以系統管理者的身份執行指令,也就是說,經由 sudo 所執行的指令就好像是 root 親自執行。
  • Linux cgroups 命令簡介
    通過了解 cgroups 技術,我們可以窺探到 linux 系統中整個資源限制系統的脈絡。從而幫助我們更好的理解和使用 linux 系統。cgroups 的主要作用實現 cgroups 的主要目的是為不同用戶層面的資源管理提供一個統一化的接口。
  • linux基礎命令和使用(基礎入門篇,看完就課上手linux作業系統)
    linux基礎命令和使用(基礎入門篇,看完就課上手linux作業系統)通常用全部大寫的變量名表示常量動態變量的申明不用指定變量類型
  • sudo 入門指南
    什麼是 sudo正如你們大部分人所知道的,sudo 用來執行需要提升權限(通常是作為 root 用戶)的命令。在這篇文章之前的簡介部分已經討論過這樣的一個例子。然而,如果你想的話,你能用 sudo 以其它(非 root )用戶運行命令。這是由工具提供的 -u 命令行選項所實現的。
  • linux應急常用命令+技巧總結
    ps aux --sort=pcpu | head -10 # 查看cpu佔用率前十的進程,有時候可以發現top發現不了的東西netstat -anpl  # 檢查當前存在的連接與監聽埠ps -ef #查看當前系統上運行的所有進程與其使用的命令w # 查看活動用戶who # 查看當前登錄用戶(tty 本地登陸  pts 遠程登錄) /var/log/utmp
  • 在 Linux 中運行特定命令而無需 sudo 密碼 | Linux 中國
    但問題是我需要 sudo 權限來開啟這個服務。正如你所知道的那樣,當我們以 sudo 用戶運行命令時,我們應該提供密碼,但我並不想這麼做,實際上我想做的是以 sudo 用戶的身份運行這個服務但無需提供密碼。假如你曾經經歷過這樣的情形,那麼我知道一個簡單的方法來做到這點。今天,在這個簡短的指南中,我將教你如何在類 Unix 的作業系統中運行特定命令而無需 sudo 密碼。