FreeBSD連載(15):檔案的屬性

1999年11月17日 19:49 王波

檔案系統與磁碟操作

  檔案在Unix下是一個非常重要的概念,Unix下不但使用檔案來保存數據,而且使用檔案來保存目錄信息、表 示硬體設備等。Unix的檔案名對大小寫敏感,例如 “FOO” 和 “foo” 是兩個不同的檔案,而且檔案名可長 達255個字符。

  檔案是按照分級的形式組織起來,每一級稱為一個目錄,其內容使用一個特殊的目錄檔案保存,而第一級目錄為根目 錄,這就形成了一種樹狀結構,最下面是根目錄 “/” ,根目錄下放有普通檔案和其子目錄,如: “/usr/” 、 “/var/” 等,而在不同的子目錄下又有自己的檔案和子目錄。

  /目錄:目錄樹的根,用於保存系統的核心檔案和系統啟動檔案,它所在的檔案系統為根檔案系統。

  /dev目錄:用於保存系統的設備檔案,占用大致固定的硬碟空間,位於根檔案系統中。

  /etc目錄:用於保存系統的配置檔案,包括passwd,rc等非常重要的檔案,也被放置到根檔案系統中。

  /bin和/sbin目錄:保存了用於系統維護目的的執行檔案,其中/sbin中的檔案通常直接用於系統維護 ,/bin為提供管理員使用系統的基本工具。也必須放置在根檔案系統上,在系統運行在單用戶模式時,只有根檔案系統安 裝到系統上時,就能夠運行這些程序進行系統維護任務。

  /tmp目錄:用於存放程序運行產生的臨時檔案,這個目錄也是每個用戶都可寫的,在系統啟動時將自動清空這個 目錄。當系統運行較大型的服務程序時,會要求較大的/tmp空間,會超過根檔案系統的空間,因此可以在其他檔案系統中 創建另一個臨時檔案目錄,使用符號連接等方法進行維護。

  /usr目錄:用於保存系統正常運行時使用的多種檔案,其中/usr/bin放置系統執行檔案,/usr/sbin 放置系統維護程序,/usr/local放置非標準的應用程序,/usr/share放置系統中的文檔和其他數 據檔案,/usr/src中放置系統的原始碼,/usr/X11R6放置X Window系統、應用程序和數據檔案。 由於這些內容非常多,/usr目錄通常為一個單獨安裝的檔案系統,占用一個硬碟分區,稱為usr檔案系統。隨著系統任 務的增長,/usr目錄中的內容也會迅速增多,還要考慮將其較大的子目錄分離出來,例如/usr/local目錄。

  /var目錄:用於保存系統運行時產生和使用的數據檔案,例如/var/log目錄用於放置系統日誌,/va r/db/pkg目錄用於放置系統軟體包的安裝記錄。很多應用程序也使用它來放置數據檔案,如news伺服器等。這個 目錄下檔案會隨系統的運行而不斷變化,其中的很多檔案會不斷增大,占用大量的磁碟空間。應該將這個目錄分離出來,這樣 即使某個進程在這個目錄下沒有限制的產生數據檔案,填充整個檔案系統,也不會影響其他目錄下的數據存儲,例如用戶在自 己目錄下的數據存儲。由於/var目錄的大小會隨著應用程序的需要改變,對於提供網路服務的伺服器,/var占用磁碟 分區應該大一些。

  /home目錄:使用它用於維護用戶的個人目錄,它的大小由用戶數量及用戶的活躍程度決定,也需要有足夠的空 間才能提供正常的服務。通常這個目錄保存在usr檔案系統中,而在根目錄下使用連接來維護。當用戶數量增加的很多的時 候,應該讓它位於一個單獨的檔案系統中。

  這些目錄開始就設計為保存不同的數據,而各個目錄會使用不同的磁碟分區。習慣於DOS/Windows的使用 者會不習慣這種使用多個檔案系統的方式,而只使用一個檔案系統,這種做法是不對的。多檔案系統可以用於分隔不同的任務 ,分隔系統風險,增加可靠性,對於用作伺服器的FreeBSD系統是必需的。

  Unix的樹狀目錄結構十分標準,那類檔案應該放置到那個目錄中都有一定的習慣。當然在不同的Unix中,具 體檔案的位置也有細微的差別,事實上在Unix發展的過程中,標準目錄樹結構的也有幾次較大的改動,但是基本結構是相 同的。由於FreeBSD有統一的版本,所有的開發者都使用同一個原始碼樹,而且使用統一的Packages Collection 機制來維護應用軟體,因此FreeBSD的目錄結構更為整齊、干淨。

  • 檔案的屬性

  由於FreeBSD是一個多用戶系統,不同的用戶對不同的檔案就應該有不同的處理權力,通常創建檔案的用戶就 擁有這個檔案,成為這個檔案的屬主。同樣,檔案也有自己的屬組,這是一個檔案的兩個重要屬性。由於檔案的屬主和組涉及 到對檔案的訪問控制,因此只有root能更改檔案的這兩個屬性,更改檔案屬主的命令為chown,更改檔案屬組的命令 為chgrp。

  由於不可能為每個用戶都單獨提供完全獨立的檔案系統,多用戶操作系統必須提供一種安全的訪問控制機制,使得用 戶既能和其他用戶共享某些檔案,又能保証各個用戶的檔案不會被非法存取或破壞。Unix分別針對屬主、同組用戶和其他 用戶共三種不同的用戶,分別設置了存取控制權限,這個權限分別為:讀、寫和執行,使用英文字母r(Read)、w(Write) 和x(eXecute)來表示。由於對屬主、組和其他用戶均有這三種權限設置,因此每個檔案共有九個權限參 數。使用 “ls -l” 命令就能看到檔案的權限設置:

$ ls -l

drwx------ 4 user wheel 512 Nov 25 17:23 Mail

-rw-rw-r-- 1 user wheel 149 Dec 4 14:18 Makefile

-rwxr-xr-x 1 user wheel 3212 Dec 4 12:36 a.out

drwxr-xr-x 1 user wheel 512 Dec 14 17:03 bin

-rw-r--r-- 1 user wheel 143 Dec 4 12:36 hello.c

drwxr-xr-x 2 user wheel 1024 Oct 16 1997 public_html

drwxrwxrwx 2 user wheel 512 Jan 3 14:07 tmp

  從上面的例子中,可以看到檔案的權限設置在列出的數據的第一列中顯示,例如檔案a.out的屬性是-rwxr-xr-x, 共顯示了十個字母的位置。其中第一個位置是用於標識檔案的種類,而非權限設置,其余九個位置分別表示三組 的三種權限設置。第二個到第四個位置表示屬主的權限分別設置為讀、寫和執行,第五個到第七個位置設置同組用戶的權限, 第八個到第十個位置設置其他用戶的權限。當指定位置上沒有顯示對應的權限,而是 “-” ,則表示不允許對應的權限。 因此a.out的權限設置為,對於屬主user的權限為讀寫和執行,對於同組用戶為讀和執行權限,對於其他用戶也是讀 和執行權限。對於目錄來講,擁有讀權限意味著用戶可以列出這個目錄下的檔案內容,寫權限使用戶可以在這個目錄下增、刪 檔案和更改檔案名,執行權限保証用戶可以使用cd進入這個目錄。

  ls輸出結果的第一個位置表示類別,例如 “d” 表示目錄, “c” 表示該檔案為字符設備檔案, “b” 表示為塊設備檔案, “l” 表示為一個符號連接。

  Unix系統內部使用數值來表示這些屬性,每一個屬性與檔案屬性中的一個二進制位相對應,如果該存取權限設置 了,對應的二進制位就是1,如果該存取權限沒有設置,對應的二進制位是0。這樣a.out的權限屬性rwxr-xr-x 用二進制來表示就是111101101,Unix下常使用八進制的形式表示,這樣這個權限是755。

  檔案的屬主和管理員可以使用命令chmod來設置或改變檔案的權限。chmod有幾種不同的使用方法,可以直 接使用八進制的權限表示方式設置屬性,或者使用屬性字母來設置或更改檔案的屬性,不同的使用方法要求不同的 chmod參數,下面是使用chmod的一些例子:

  chmod 750 a.out :改變a.out的權限為750﹔

  chmod a+x a.out :對所有用戶增加a.out的執行權限,
  a(All)表示所有用戶﹔

  chmod u=rwx a.out :設置屬主的權限為讀、寫和執行
  u(user)表示屬主用戶﹔

  chmod g+rw a.out :增加同組用戶的讀寫權限,
  g(group)表示同組用戶﹔

  chmod o-w a.out :減少其他用戶的寫權限,
  o(others)表示其他用戶﹔

  chmod go= a.out :清除同組和其他用戶的所有權限﹔

  chmod o=u-w a.out :設置其他用戶的權限為減去寫權限的屬主權限﹔

  權限755是最常見的檔案權限設置,這種屬性的檔案允許其他用戶可以訪問這個檔案,但不可以更改,如果不打算 讓其他用戶訪問檔案,檔案的存取權限可以設置為700。檔案在創建的時候,系統使用掩碼來決定檔案的權限,掩碼的二進 制對應位為1的,檔案屬性的對應位就設置為0,例如當掩碼的八進制表示為022時(二進制為000010010),創 建的檔案權限就為755(111101101)。檔案掩碼使用umask命令來設置,例如使用 “umask 027 ” 設置掩碼為027,則創建的檔案權限為750,其他用戶將對這個檔案沒有任何權限。可以在啟動資源檔案或者在登錄 類別中設置中設置用戶的掩碼。

  目錄需要設置執行位,以允許用戶能使用cd命令進入這個目錄中

  當一個檔案的權限設置完畢之後,在一個進程試圖訪問這個檔案時,系統就比較這個進程的屬主和屬組與檔案的屬主 和屬組,判斷這個進程是否具備訪問權限。由於每個進程的屬主和屬組標識是由啟動這個進程的用戶決定的,因此一個用戶啟 動的進程就具備其本身對檔案的訪問權限。

  除了讀、寫和執行權限以外,對於可執行的程序還有另外兩個非常重要的屬性:設置屬主身份(setuid, Set User ID) 權限和設置組身份(setgid, Set Group ID)權限,這兩個屬性允許某個程序 可以更改自己的進程標識為程序檔案屬主或組,因而就可以具備該程序檔案屬主或屬組的訪問權限,而不再僅僅是啟動進程的 用戶的訪問權限,這樣就能完成特定的任務。很多系統程序,例如su,就是通過這個特性來完成從執行進程時的普通用戶身 份到root用戶身份的轉化的,因此這兩個屬性對於系統安全至關重要。不是必要的系統程序,不能具備這些屬性。

  可以使用 “chmod +s file” 或 “chmod g+s file” 來設置這兩個屬性,或者 使用 “chmod 4755 file” 、 “chmod 2755 file” 八進制方式來設置setuid 或setgid屬性。

  • 檔案的連接和符號連接

  Unix中使用i節點(i node)來記錄真實的物理檔案及其位置,檔案名只是指向i節點的一個連接。因此 每個檔案可以有多個名字,每個名字就稱為檔案的一個連接,而同一個檔案的所有連接所指向的i節點件完全相同。但在刪除 時只有全部刪除這個i節點的全部連接,才能刪除i節點、即刪除這個檔案本身。

$ ln l1 l2

$ ls -l l*

-rwxr-xr-x 2 user wheel 53212 Dec 4 12:36 l1

-rwxr-xr-x 2 user wheel 53212 Dec 4 12:36 l2

$

  上面的例子使用ln創建了一個連接,然後在ls的結果中可以看到第二列的數字為2,這表示這個檔案有兩個連接 。這樣的連接可以建立在不同的目錄中,但所有連接所在的目錄必須在同一個檔案系統中,才能使用同樣的i節點。由於連接 是直接指向標識物理檔案的i節點,因此這種連接又稱為硬連接。

  另一種更靈活的連接方式是符號連接,它沒有指向物理檔案的i節點,而是直接指向目錄樹上的另一個入口,那麼當 系統訪問這個檔案時,就沿著它指向的目錄樹的位置去查找具體檔案。這樣就能對任何檔案系統中的檔案和目錄建立連接,因 此稱為軟連接。符號連接可以跨越檔案系統,靈活性很大,能夠突破物理檔案系統的限制維護目錄樹的一致性,對於系統管理 和維護很有用。但是這種連接方式需要對目錄樹進行多次查找,增加了檔案操作的額外步驟,因此效率較低,因此不應該使用 多級連接,及某個符號連接指向的目錄還是一個符號連接,甚至發生符號連接的循環。應該盡量少用符號連接,並避免多級符 號連接及符號連接的循環。

$ ln -s l1 /root/files

$ ls -l l*

lrwxrwxrwx 1 user wheel 12 Dec 4 12:36 l1 -> /root/files

$