文件在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
$