文件權限與屬性

出自 Arch Linux 中文维基

文件系統權限屬性來規範系統進程與文件和目錄之間的交互。

警告: 權限和屬性設置只能防範來自已經啟動了的當前系統的攻擊。為了防止數據被能物理訪問該機器的人的接觸,必須同時使用磁盤加密.

查看權限[編輯 | 編輯原始碼]

使用ls命令的-l選項查看為目錄內容設置的權限(或文件模式),例如:

$ ls -l /path/to/directory
total 128
drwxr-xr-x 2 archie users  4096 Jul  5 21:03 Desktop
drwxr-xr-x 6 archie users  4096 Jul  5 17:37 Documents
drwxr-xr-x 2 archie users  4096 Jul  5 13:45 Downloads
-rw-rw-r-- 1 archie users  5120 Jun 27 08:28 customers.ods
-rw-r--r-- 1 archie users  3339 Jun 27 08:28 todo
-rwxr-xr-x 1 archie users  2048 Jul  6 12:56 myscript.sh

第一欄是我們必須關注的內容。 以 drwxrwxrwx +為例,每個字符的含義在下表中說明:

d rwx rwx rwx +
文件類型,技術上不屬於其權限。 有關可能值的說明,請參閱 info ls -n "What information is listed" 命令的輸出。 所有者對文件的權限,如下所述。 該組對該文件的權限,如下所述。 所有其他用戶對該文件的權限,如下所述。 一個指定備用訪問方法是否適用於該文件的字符。 當此字符是空格時,沒有備用訪問方法。 .字符表示具有安全上下文的文件,但沒有其他備用訪問方法。 具有任何其他備用訪問方法的文件用 +字符標記,例如在使用訪問控制列表 (ACL) 的情況下.

權限三元組(也就是上面例子中的rwx)可以由以下字符(權限位)構成:

字符 文件效果 目錄效果
讀權限(第一個字符) - 不能讀取該文件 不顯示目錄裡的內容
r 可以讀取該文件 能顯示目錄裡的內容
寫權限(第二個字符) - 不能修改該文件 不能修改目錄中的內容
w 可以修改該文件 能修改目錄中的內容(創建、重命名或刪除文件或子目錄);需要同時設置執行權限,否則本權限無效。
執行權限(第三個字符) - 不能執行該文件 無法使用 cd 命令訪問該目錄
x 可以執行該文件 能使用 cd 命令訪問該目錄。這是實踐中唯一一個算是可以從父目錄繼承而來的權限。實際上,如果某文件或目錄路徑中的任何一個目錄沒有設置 x 權限, 就算最終訪問的文件或目錄設置了對應的權限也是打不開的。請參考path_resolution(7) 來了解更多。
s 當出現在用戶(所有者)權限三元組時,代表 setuid 位; 當出現在組權限三元組時,代表 setgid 位;不會出現在對其他用戶權限的三元組中;同時意味着設置了 x 權限。
S s 相同,但是未設置 x 權限;普通文件中很少見,並且對於目錄是無效的。
t 粘滯位,只存在於對其他用戶權限的三元組中;同時意味着設置了 x 權限。
T t 相同,但是未設置 x 權限 ;普通文件中很少見。

請參考 info Coreutils -n "Mode Structure"chmod(1) 以獲得更詳細的說明。

提示:您可以用 namei -l path 命令查看文件或者目錄沿路的權限

案例[編輯 | 編輯原始碼]

讓我們用一些案例來解釋說明:

drwx------ 6 archie archie  4096 Jul  5 17:37 Documents

Archie 具有對 Document 目錄的完全訪問權限。它可以列出、創建和重命名或刪除 Documents 中的任何文件,無論其中文件的權限是什麼。而它訪問文件的能力取決於具體文件的權限。

dr-x------ 6 archie archie  4096 Jul  5 17:37 Documents

Archie 擁有完全訪問權限,但他們不能創建、重命名或刪除任何文件。他們可以列出文件,並且(如果文件的權限允許)可以訪問文檔中的現有文件。

d-wx------ 6 archie archie  4096 Jul  5 17:37 Documents

Archie 不能在 files 目錄中執行 ls ,但是如果它知道現有文件的名稱,就可以列出、重命名、刪除或(如果文件的權限允許)訪問該文件。此外,它們還能夠創建新文件。

d--x------ 6 archie archie  4096 Jul  5 17:37 Documents

Archie 只能夠在文件權限允許的情況下訪問已知的文件。它不能列出目錄中的文件,也無法創建、重命名或者刪除任何文件。

要記得,我們在此介紹的是目錄權限,這與單個文件權限無關。創建一個新文件時,修改的是目錄。這就是為什麼您需要有目錄的寫權限。

接下來我們看一些文件權限方面的例子:

-rw-r--r-- 1 archie web  5120 Jun 27 08:28 foobar

在這裡,我們可以看到第一個字母不是 d 而是 -。所以我們知道它是一個文件,而不是一個目錄。接下來,所有者的權限是rw-。所有者並沒有擁有全部的三個權限可能很奇怪,但這個文件作為一個文本文件而不是一個可執行文件時,並不需要x 權限(但如果它包含 python 代碼之類的內容,那麼它很可能是可執行文件),我們可以用 Gedit、EMACS 等文本編輯器或者 R 之類的軟件來讀取它。該文件的組權限為 r-- ,因此該組的成員可以讀取文件,但不能以任何方式對其進行寫入/編輯,實際上就是把它設置為只讀。最後是對其他用戶的權限,被設置為與組權限一致,也是只讀。

修改權限[編輯 | 編輯原始碼]

chmod 是 Linux 和其他 Unix-like 操作系統中用來修改文件或者目錄權限的命令。

以字符形式修改權限[編輯 | 編輯原始碼]

想要修改文件的權限(或者叫訪問模式),請在終端裡使用 chmod 命令。以下是該命令的基本結構:

chmod who=permissions filename

其中的 who 是一個或者多個字母,代表要指定權限的對象,可以為:

  • u: 擁有該文件的用戶
  • g: 該文件所屬的用戶組 .
  • o: 所有其他用戶
  • a: 以上所有,等效於 ugo.

權限和上面 #查看權限所述的相同 (r, wx).

現在看一下使用這個命令的一些示例。假設您對「文檔」目錄進行了嚴格的保護,並希望拒絕除您之外的所有人在其中讀取、寫入和執行(或在本例中是拒絕搜索或查看)的權限。

修改前: drwxr-xr-x 6 archie web 4096 Jul 5 17:37 Documents

$ chmod g= Documents
$ chmod o= Documents

修改後: drwx------ 6 archie web 4096 Jul 6 17:32 Documents

在這裡,因為您想要禁止所有權限,所以不要在 = 後面輸入任何內容。如此修改後,除了文件所有者的權限為 rwx 之外,其他權限都是 -

您可以使用如下命令來恢復原來的狀態:

再次修改前:drwx------ 6 archie web 4096 Jul 6 17:32 Documents

$ chmod g=rx Documents
$ chmod o=rx Documents

再次修改後:drwxr-xr-x 6 archie web 4096 Jul 6 17:32 Documents

在下一個例子中,您想給組及其他用戶讀取和執行權限,所以您可以在 = 後面輸入相應的權限 rx,記得不要帶空格。

您可以在 who 的地方輸入多個字母,來同時給多個對象設置權限,如:

$ chmod go=rx Documents
注意: chmod 命令中的 who 字母或者權限位()字符的順序是無關緊要的。chmod go=rx filechmod og=xr file 這兩個命令的含義完全相同

接下來我們考慮第二個例子,假設您想讓自己和 web 用戶組中的用戶(可能是您的同事)有 foobar 這個文件的讀寫權限, 但其他人只能讀取它。那麼操作如下:

修改前: -rw-r--r-- 1 archie web 5120 Jun 27 08:28 foobar

$ chmod g=rw foobar

修改後:-rw-rw-r-- 1 archie web 5120 Jun 27 08:28 foobar

這與第一個示例完全相同,但使用的是文件,而不是目錄,並且您授予的是寫入權限(這只是為了給出授予每個權限的示例)。

字符形式的捷徑[編輯 | 編輯原始碼]

chmod 命令允許使用 +- 而不是=從現有集合中添加和減去權限。這與上面的命令不同,後者實質上是重設權限(例如,要將權限從r--更改為rw- ,您仍然需要在 chmod 命令的=之後包含 rw。如果遺漏了r ,那麼在使用=重設權限時,它將取消r的權限。使用+-可以通過添加或刪除當前的權限集來避免這種情況)。

讓我們用 +- 的方式復現一下前面給組添加寫權限的例子:

修改前: -rw-r--r-- 1 archie web 5120 Jun 27 08:28 foobar

$ chmod g+w foobar

修改後:-rw-rw-r-- 1 archie web 5120 Jun 27 08:28 foobar

另一個例子,取消所有用戶和組的寫入權限。

修改前: -rw-rw-r-- 1 archie web 5120 Jun 27 08:28 foobar

$ chmod a-w foobar

修改後: -r--r--r-- 1 archie web 5120 Jun 27 08:28 foobar

另一個不同的捷徑是特殊的 X 模式:實際上不存在這個模式,但它通常與 -R 選項(遞歸)一起使用,以設置只針對目錄的執行權限,而不修改常規文件的權限,例如:

$ chmod -R a+rX ./data/

複製權限[編輯 | 編輯原始碼]

您可以讓 chmod 把某對象(比如所有者)的權限複製給其他對象(比如組或者所有人)。想要做到這一點,在 = 後面不要跟權限(rwx),而是輸入另一個 who 字母。比如:

修改前 -rw-r--r-- 1 archie web 5120 Jun 27 08:28 foobar

$ chmod g=u foobar

修改後 -rw-rw-r-- 1 archie web 5120 Jun 27 08:28 foobar

這個命令的意思就是「把對組(g=)的權限設置為與所有者(=u)的權限相同」。請注意,您不能複製一組權限,也不能授予新的權限,以下是錯誤示範,chmod 會報錯:

$ chmod g=wu foobar

數字形式[編輯 | 編輯原始碼]

chmod 也可以用數字來設置權限。

使用數字是另一種方法,它允許您同時編輯所有者、組和其他人的權限,以及setuid、setgid和粘滯位。命令的基本結構如下:

$ chmod xxx filename

xxx 部分是一個三位數,其中的每一位可以是0到7之間的任何數字。第一位數字指所有者的權限,第二位數字指組的權限,而第三位數字指所有其他人的權限。

在這個數字表示法中,權限 rwx所對應的數值是:

r=4
w=2
x=1

要得到這個三位數,您要考慮為所有者、組和所有其他人設置哪些權限,然後將其對應的數值累加起來。例如,如果希望授予目錄的所有者讀寫和執行權限,並希望 group 和其他所有人只有讀寫權限,那麼通過計算可以得到如下數值:

  • 所有者: rwx=4+2+1=7
  • 組: r-x=4+0+1=5
  • 其他人: r-x=4+0+1=5
$ chmod 755 filename

這就相當於使用如下命令:

$ chmod u=rwx filename
$ chmod go=rx filename

若要以數字形式查看文件或目錄的現有權限,請使用stat(1)命令:

$ stat -c %a filename

%a 指定以數字形式輸出文件權限。

大多數目錄被設置為 755 以允許所有者讀取、寫入和執行,但拒絕被其他所有人寫入;文件通常是644 以允許所有者讀取和寫入,但允許其他所有人讀取;請參考最後一個關於不可執行文件缺少x權限的說明,此處同理。

為了用實例來說明這一點,我們用數字方式復現一下前面舉過的例子:

修改前:-rw-r--r-- 1 archie web 5120 Jun 27 08:28 foobar

$ chmod 664 foobar

修改後: -rw-rw-r-- 1 archie web 5120 Jun 27 08:28 foobar

如果這是一個可執行文件,同時您想向所有者和組授予可執行權限,則權限數字為774。或者,如果您希望每個人都只具有讀取權限,則數字將為444。將r視為4,w視為2,以及x視為1,這可能是計算chmod xxx 文件名的權限數值最簡單的方法。

但還有一種二進制方法,其中每個權限都代表一個二進制數,最後再將其轉換為一個數字。它有點複雜,但為了完整起見,在此也介紹該方法。

對於以下權限組合:

-rwxrwxr-x

如果您在每個授予的權限下寫1,而在每個未授予的權限下寫0,則結果如下:

-rwxrwxr-x
 111111101

然後把它當成二進制數進行轉換:

000=0	    100=4
001=1	    101=5
010=2	    110=6
011=3	    111=7

因此,上述值為775。

如果我們想從組中刪除寫權限:

-rwxr-xr-x
 111101101

因此,該值將為755,您可以使用 chmod 755 文件名刪除可寫權限。無論使用哪種方法,您最終都會得到相同的三位數。使用文本還是數字取決於個人偏好和打字速度。如果您希望將目錄或文件還原為默認權限(例如所有者有讀寫和執行權限,但拒絕其他所有人的寫權限),則使用chmod 755/644 文件名可能會更快。但如果您要將權限更改為比較少見的組合,則使用文本方法可能會更簡單、更快,而不是嘗試將其轉換為數字,這可能會導致錯誤。對於只需要偶爾使用chmod的用戶來說,這兩種方法的速度都沒有顯著的差異。

您也可以用數字形式設置setuid, setgidsticky 權限位。

setuid=4
setgid=2
sticky=1

比如 chmod 2777 filename 將為每個人設置讀/寫/可執行位,並啟用setgid位。

批量 chmod[編輯 | 編輯原始碼]

通常,目錄和文件不應具有相同的權限。如果需要批量修改目錄樹,請使用find選擇性地修改其中一個或另一個。

若要只把目錄權限修改為 755:

$ find directory -type d -exec chmod 755 {} +

若要只把文件權限修改為 644:

$ find directory -type f -exec chmod 644 {} +

修改所有者[編輯 | 編輯原始碼]

chown 能夠修改文件或者目錄的所有者,這在某些情況下會更簡單快捷。

比如,您要使用GParted為備份數據創建一個新分區。Gparted以root身份執行所有操作,因此默認情況下所有內容都屬於root。這一切都很好,但當要向掛載的分區寫入數據時,常規用戶會沒有權限。

brw-rw---- 1 root disk 8,    9 Jul  6 16:02 sda9
drwxr-xr-x 5 root root    4096 Jul  6 16:01 Backup

若您所見,/dev是由root所有的,而掛載點(/media/Backup也是一樣。如果我們要修改掛載點的所有者,您可以執行如下命令:

修改前: drwxr-xr-x 5 root root 4096 Jul 6 16:01 Backup

# chown archie /media/Backup

修改後: drwxr-xr-x 5 archie root 4096 Jul 6 16:01 Backup

現在在無需調整權限的情況下,這個分區就可以由新的所有者 archie 寫入了。(作為所有者,它本身就擁有 rwx 權限)

注意:
  • chown 總是會清除 setuid 和 setgid 權限位
  • 非 root 用戶不能使用 chown 來把他們自己擁有的文件「送給」其他用戶

訪問控制列表(ACL)[編輯 | 編輯原始碼]

Access Control Lists 通過允許為任何用戶或組設置對任何文件的權限,為文件系統提供了額外的、更靈活的權限機制。

Umask[編輯 | 編輯原始碼]

umask 實用程序用於控制文件創建模式掩碼,該掩碼確定了新創建文件的權限位的初始值。

文件屬性[編輯 | 編輯原始碼]

除了控制用戶和組讀、寫和執行權限的文件權限之外,還有幾個文件系統支持文件屬性,這些屬性可以進一步自定義允許的文件操作。

警告: 默認情況下, cprsync 和其他類似的程序不會保留文件屬性

e2fsprogs 軟件包內有 lsattr(1)chattr(1) 這兩個可以列出和修改文件屬性的工具。

以下是一些有用的屬性,但並非所有的文件系統都支持每個屬性。

  • a - 僅追加(append only):文件只能以追加的方式打開。
  • c - 壓縮(compressed):為文件啟用文件系統級的壓縮。
  • i - 不變(immutable):無法被修改、刪除、重命名或創建指向它的鏈接。只能由root用戶設置。
  • j - 數據日誌(data journaling):為文件的寫入和元數據啟用日誌
  • m - 不壓縮(no compression):為文件禁用文件系統級的壓縮。
  • A - 禁用atim更新(no atime update):文件的 atime (訪問時間)將不會被修改。
  • C - 禁用寫時拷貝(no copy on write): 對於支持寫時拷貝的文件系統,禁用寫時拷貝。

查看 chattr(1) 以獲得更詳細的文件屬性列表以及它們的作用。

比如,如果您想給某個文件設置不變(immutable)屬性,使用如下命令:

# chattr +i /path/to/file

要刪除文件上的屬性,只需把 + 改為 -

擴展屬性[編輯 | 編輯原始碼]

根據 xattr(7):「擴展屬性是與文件和目錄永久關聯的鍵值對」。有四個擴展屬性類: security、 system、 trust 和 user。

警告: 默認情況下,cprsync 和其他類似的程序不會保留文件屬性。請參考 #保留擴展屬性.

擴展屬性還用於設置能力(Capabilities).

用戶擴展屬性[編輯 | 編輯原始碼]

用戶擴展屬性可用於存儲有關文件的任意信息,比如:

$ setfattr -n user.checksum -v "3baf9ebce4c664ca8d9e5f6314fb47fb" foo.txt

使用getfattr來顯示擴展屬性:

$ getfattr -d foo.txt
# file: foo.txt
user.checksum="3baf9ebce4c664ca8d9e5f6314fb47fb"

如果要刪除擴展屬性:

$ setfattr -x user.checksum foo.txt

保留擴展屬性[編輯 | 編輯原始碼]

命令 所需的選項
cp --preserve=mode,ownership,timestamps,xattr
mv 默認會保留[注 1]
tar 創建tar檔時用 --xattrs ,解壓時用 --xattrs-include='*'
bsdtar 解壓時用 -p
rsync --xattrs
  1. 當目標文件系統不支持擴展屬性時,mv 會靜默地丟棄這些擴展屬性。

要在使用文本編輯器的時候保留擴展屬性,您需要把他們配置為在保存時截斷(truncate)文件而非使用 rename(2).[1]

技巧和竅門[編輯 | 編輯原始碼]

Preserve root[編輯 | 編輯原始碼]

使用 --preserve-root 選項來阻止 chmod 遞歸地從 / 修改文件權限。 這可以防止在系統範圍內刪除可執行位,從而破壞系統。要每次使用此標誌,請在alias中設置它。參見 [2].

參見[編輯 | 編輯原始碼]