面試必問Linux 命令su和sudo的區別解析
之前一直對 su
和 sudo
這兩個命令犯迷糊,最近專門搜瞭這方面的資料,總算是把兩者的關系以及用法搞清楚瞭,這篇文章來系統總結一下。
1. 準備工作
因為本篇博客中涉及到用戶切換,所以需要提前準備好幾個測試用戶,方便後續切換。
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
用戶。
2. su 命令介紹及主要用法
首先需要解釋下 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用戶的權限。但還是有差異,接著往後看。
3. sudo 命令介紹及主要用法
首先還是解釋下 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 - su -
還有一個命令:
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 部分第二條,這篇文章不再贅述。
4. 二者的差異對比
二者的差異對比:
su - sudo su -
兩種方式的差異也顯而易見:如果我們的Linux系統有很多用戶需要使用的話,前者要求所有用戶都知道root用戶的密碼,這顯然是非常危險的;後者是不需要暴露root賬戶密碼的,用戶隻需要輸入自己的賬戶密碼就可以,而且哪些用戶可以切換到root,這完全是受root控制的(root通過設置 /etc/sudoers
實現的),這樣系統就安全很多瞭。
到此這篇關於面試必問Linux 命令su和sudo的區別解析的文章就介紹到這瞭,更多相關Linux 命令su和sudo內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!