Learning Objectives
- 看懂 ls -l 的權限欄位:檔案類型、擁有者、群組與其他人的 rwx
- 用 id、groups 查看自己的身分,說明 r、w、x 對檔案與目錄的不同意思
- 用 chmod 的數字寫法(644、755、600、640)與符號寫法(u+x、g-w、o=r)調整權限,讓腳本可以執行
- 用 sudo 執行需要管理權限的指令,知道 sudo 不會讓「>」重導取得權限,要改用 | sudo tee
- 用 sudo chown 變更擁有者,用 adduser 或 useradd -m 建立使用者,用 usermod -aG 加入群組
多人共用的系統,需要權限
Linux 從一開始就是多使用者的系統:同一台伺服器上可能有好幾位使用者,還有網站、資料庫等服務各自用不同的帳號執行。 為了讓大家不會互相讀到或改壞對方的檔案,每個檔案與目錄都記錄著三件事:
- 擁有者(owner):這個檔案屬於哪個使用者
- 群組(group):這個檔案屬於哪個群組
- 權限:擁有者、群組成員、其他人,各自能不能讀(r)、寫(w)、執行(x)
系統管理員 root 不受權限限制,什麼都能做。Ubuntu 預設不讓你直接用 root 登入,而是讓安裝時建立的使用者用 sudo 暫時取得管理權限。
上一課出現過的 Permission denied,就是權限檢查沒有通過時的錯誤訊息。
看懂 ls -l 的權限欄位
$ ls -l hello.sh
-rwxr-xr-- 1 student student 39 Oct 29 14:30 hello.sh
| 欄位 | 這個例子 | 意思 |
|---|---|---|
| 第 1 個字元 | - |
檔案類型:- 一般檔案、d 目錄、l 符號連結 |
| 第 2~4 個字元 | rwx |
擁有者(user,u)的權限:可讀、可寫、可執行 |
| 第 5~7 個字元 | r-x |
群組(group,g)的權限:可讀、不可寫、可執行 |
| 第 8~10 個字元 | r-- |
其他人(others,o)的權限:只能讀 |
1 |
連結數 | |
student(第一個) |
擁有者 | |
student(第二個) |
群組 | |
39 |
大小(位元組) | |
Oct 29 14:30 |
最後修改時間 |
- 表示「沒有這項權限」。系統檢查權限時只看一組:你是擁有者就看第一組;不是擁有者但在這個群組裡,看第二組;都不是就看第三組。
用 id 或 groups 查看自己的身分:
$ id
uid=1000(student) gid=1000(student) groups=1000(student),4(adm),27(sudo)
Ubuntu 建立使用者時,會同時建立一個同名的群組當作主要群組,所以常看到 student student 這樣的寫法。
安裝時建立的第一個使用者會被加入 sudo 群組(可以使用 sudo)與 adm 群組(可以讀取 /var/log 裡的系統紀錄檔);實際的系統可能還會列出其他群組。
r、w、x 對檔案與目錄的意思不同
| 權限 | 對檔案 | 對目錄 |
|---|---|---|
| r(read,讀取) | 讀取檔案內容(cat、less) |
列出目錄裡有哪些名稱(ls) |
| w(write,寫入) | 修改檔案內容 | 在目錄裡新增、刪除、改名檔案(同時需要 x) |
| x(execute,執行) | 把檔案當成程式執行 | 進入目錄(cd),以及存取目錄裡的檔案 |
兩個容易誤會的地方:
- 能不能刪除一個檔案,看的是它所在目錄的 w,不是檔案本身的 w。
- 目錄少了 x,就算有 r 也進不去,裡面的檔案也讀不到。目錄通常是
r-x或rwx成對出現。
Ubuntu 21.04 起,新使用者的家目錄權限是 drwxr-x---(750):其他一般使用者既不能進入,也看不到裡面有什麼。
chmod:調整權限
數字寫法:r=4、w=2、x=1,每一組把有的權限加起來,三組依序寫成三個數字。
| 數字 | 權限 | 常見用途 |
|---|---|---|
644 |
rw-r--r-- |
一般檔案:自己可以改,其他人只能讀 |
755 |
rwxr-xr-x |
程式、腳本與目錄:大家都能執行或進入,只有自己能改 |
600 |
rw------- |
私密檔案:只有自己能讀寫,例如 SSH 私鑰 |
640 |
rw-r----- |
自己能讀寫、同群組的人能讀,其他人完全不能看 |
700 |
rwx------ |
只有自己能進入的目錄 |
符號寫法:對象(u 擁有者、g 群組、o 其他人、a 全部)+ 動作(+ 加上、- 拿掉、= 設成)+ 權限。
| 寫法 | 作用 |
|---|---|
chmod u+x hello.sh |
擁有者加上執行權限 |
chmod g-w report.txt |
群組拿掉寫入權限 |
chmod o=r report.txt |
其他人的權限設成只有讀取 |
chmod +x hello.sh |
沒寫對象時等於 a,三組都加上執行權限 |
chmod -R 755 project |
-R 連同目錄底下的所有檔案一起改 |
數字寫法一次決定全部九個位置;符號寫法只改你指定的部分,其他保持不變。
只有檔案的擁有者(或 root)可以改它的權限,改別人的檔案會出現 Operation not permitted。
執行腳本需要 x 權限。 新建立的文字檔通常沒有執行權限:
$ ./hello.sh
bash: ./hello.sh: Permission denied
$ bash hello.sh
Hello from hello.sh
$ chmod u+x hello.sh
$ ./hello.sh
Hello from hello.sh
./hello.sh 是把檔案本身當成程式執行,需要 x;bash hello.sh 是執行 bash,讓 bash 讀取這個檔案,所以只需要 r。
前面的 ./ 表示「目前目錄裡的」,因為目前目錄不在系統尋找指令的路徑裡,只打 hello.sh 會找不到指令。
sudo 與 Permission denied
系統檔案多半屬於 root。一般使用者讀不到或改不了時,會看到 Permission denied:
$ cat /etc/shadow
cat: /etc/shadow: Permission denied
$ ls -l /etc/shadow
-rw-r----- 1 root shadow 85 Oct 29 14:30 /etc/shadow
/etc/shadow 存放加密過的密碼,只有 root 與 shadow 群組能讀。在指令前面加上 sudo,以 root 的身分執行那一個指令:
sudo cat /etc/shadow
| 寫法 | 作用 |
|---|---|
sudo 指令 |
以 root 身分執行一個指令;第一次要輸入自己的密碼(不是 root 的密碼) |
sudo -l |
列出自己可以用 sudo 執行哪些指令 |
sudo -i |
開一個 root 的 shell,提示字元變成 #;用完記得 exit |
只有 sudo 群組的成員可以使用 sudo。輸入密碼時畫面不會顯示任何字元;輸入後短時間內再用 sudo,不必重新輸入。
sudo 不會讓重導取得權限。 下面這行仍然會失敗:
$ sudo echo "10.0.2.20 fileserver" >> /etc/hosts
bash: /etc/hosts: Permission denied
sudo 只讓 echo 以 root 執行,但 >> 是由你自己的 shell(一般使用者)負責開檔寫入的。正確的做法是把文字用管線交給以 root 執行的 tee:
echo "10.0.2.20 fileserver" | sudo tee -a /etc/hosts # -a 附加到檔案最後
echo "新的內容" | sudo tee /etc/某個檔案 # 不加 -a 會覆蓋整個檔案
tee 會把收到的文字寫進檔案,同時印在螢幕上;不想看到可以在最後加 > /dev/null。
需要 sudo 的時候才用 sudo。用 sudo 執行之前,先想清楚這個指令會改到什麼;以 root 身分執行的
rm不會被任何權限擋下。
變更擁有者與建立使用者
chown(change owner) 變更擁有者與群組。把檔案「送給」別人需要 root 權限,所以一般要加 sudo:
| 寫法 | 作用 |
|---|---|
sudo chown alice report.txt |
擁有者改成 alice |
sudo chown alice:alice report.txt |
擁有者與群組都改成 alice |
sudo chown -R alice:alice project |
連同目錄底下的所有檔案一起改 |
chgrp team project |
只改群組(自己是擁有者、而且屬於 team 群組時,不需要 sudo) |
建立使用者有兩個指令:
| 指令 | 說明 |
|---|---|
sudo adduser alice |
Ubuntu 建議使用的互動式工具:自動建立家目錄、設定 bash、詢問密碼與基本資料 |
sudo useradd -m -s /bin/bash bob |
底層工具:-m 建立家目錄、-s 指定 shell;沒有 -m 就不會建立家目錄,沒有 -s 時 Ubuntu 24.04 預設是 /bin/sh。建立後要另外用 sudo passwd bob 設定密碼 |
加入群組用 usermod -aG:
sudo usermod -aG sudo alice # 讓 alice 可以使用 sudo
groups alice # 確認:alice : alice sudo
-a(append)表示「加上」;少了 -a,-G 會把使用者原本的附加群組整個換掉。
加入群組後,要等那位使用者重新登入才會生效。其他相關指令:sudo groupadd team 建立群組、sudo userdel -r bob 刪除使用者連同家目錄。
看懂剛才的結果
/var/log/syslog的權限是-rw-r-----、群組是adm。你屬於 adm 群組,適用第二組權限r--,所以不用 sudo 也能讀;/etc/shadow的群組是 shadow,你不在裡面,只能看第三組---。sudo echo … >>失敗、| sudo tee -a成功:差別在於「誰負責寫入檔案」。adduser alice沒有 sudo 時直接被拒絕:建立使用者要修改/etc/passwd、/etc/shadow,只有 root 能做。chown沒有 sudo 也被拒絕,即使 report.txt 是你自己的檔案;一般使用者不能把檔案的擁有權交給別人。- 擁有者變成 alice 之後,你就不再是這個檔案的擁有者,想再改它的權限也需要 sudo 了。
想一想:權限欄位與 chmod
ls -l 顯示 -rw-r----- 1 alice staff 120 Oct 29 14:30 notes.txt。你是 student,屬於 staff 群組,可以對 notes.txt 做什麼?
chmod 640 secret.txt 之後,權限欄位會顯示什麼?
run.sh 的權限是 -rw-r--r--,執行 ./run.sh 出現 Permission denied。下列哪一個做法無法讓它執行?
想一想:目錄、sudo 與使用者
目錄 project 的權限是 drw-r--r--(644),擁有者是你。執行 cd project 會怎樣?
要在只有 root 能寫入的 /etc/hosts 最後加上一行,下列哪一個寫法正確?
alice 原本屬於 alice、docker 兩個群組,管理員執行 sudo usermod -G sudo alice(少了 -a)之後,alice 屬於哪些群組?
重點精華回顧
- 每個檔案都有擁有者、群組與三組權限(擁有者 u、群組 g、其他人 o);
ls -l的第一欄就是類型加上 rwx。 id、groups查看自己的使用者編號與群組;Ubuntu 的第一個使用者屬於 sudo 與 adm 群組。- 對檔案:r 讀、w 改、x 執行;對目錄:r 列出名稱、w 新增刪除、x 進入。刪除檔案看的是目錄的 w。
chmod數字寫法 r=4、w=2、x=1(644、755、600、640);符號寫法u+x、g-w、o=r;-R遞迴。./腳本需要 x 權限,bash 腳本只需要 r。sudo以 root 身分執行一個指令,輸入的是自己的密碼;sudo echo > 系統檔案仍會被拒,要用| sudo tee(附加用tee -a)。sudo chown 使用者:群組 檔案變更擁有者;sudo adduser或sudo useradd -m -s /bin/bash建立使用者;sudo usermod -aG 群組 使用者加入群組,記得-a。