UNIX 計算機上的文件采用層次結構進行組織。這個層次結構的最高層是 /,一般稱其為“斜線”或者“根目錄”。
如果您將工作目錄更改為 /,並運行 ls,那麼您將看見幾個具有神秘名稱的子目錄(如 etc、bin、var、home 和 tmp)。盡管 UNIX 現在支持長文件名,但是這些頂層目錄名字中的大多數可以追溯到大約 30 年前,即 UNIX 剛剛出現的時候。類似地,根據同樣長期存在的約定,包含在 / 中的每個目錄都用於某個特殊的目的:
/bin 僅僅是包含應用程序和實用工具的許多目錄中的一個。然而,/bin 通常包含那些對於系統操作而言基本的實用工具。因此,Shell 文件操作命令如 cp 和 chmod、壓縮和解壓縮,以及診斷命令都位於 /bin 中。
/sbin 同樣包含那些對於系統操作和維護而言至關重要的實用工具。然而,只有超級用戶才能夠執行 /sbin 中的程序,因此這個目錄稱為“superuser-bin”或者 /sbin。
/dev 包含您的系統中所安裝的所有硬件,包括終端和 USB 設備(以及從物理上連接到這台計算機的其他外圍設備)、偽終端(用於與 X 終端窗口進行交互),以及硬盤驅動器,等等。
/etc(常常發音為“etsee”)專門用於系統配置。/etc 目錄包含用於系統守護進程、啟動腳本、系統參數和更多其他方面的配置文件。
/home 包含用戶的 home 目錄。例如,如果您的登錄名是 joe,那麼目錄 /home/joe 就是您的個人文件存儲庫。
/lib 用於存儲基本的系統庫文件。在現代 UNIX 中,通常共享系統庫,這意味著並不是每個二進制文件都鏈接和包括這些庫(那樣的話,至少將會浪費空間),但是當需要該庫的時候,按需要加載它,並且同時可以由許多應用程序進行共享。因此,與 UNIX 一同安裝的核心應用程序和實用工具的運行都需要使用 /lib 中的庫,並且您至少需要擁有少量相應的庫文件,以便從源代碼創建新的可執行文件。其中所有的文件都是至關重要的,損壞或者刪除(無論是有意的還是無意的)某個文件就可能使系統變得無法使用。
/mnt 是“mount”的縮寫,是裝入硬盤驅動器分區和其他設備的標准位置。如果您希望查看當前裝入的並且可訪問的所有設備,只需要運行 mount 命令。
/tmp 或者“temporary”,是系統范圍的暫存存儲區。您的 Web 服務器可能會將會話數據文件保存在這裡,並且其他實用工具將使用 /tmp 中的空間對中間結果進行緩存。通常認為 /tmp 中的文件在使用後即被丟棄。實際上,您的系統管理員可能會在每天晚上刪除其中比某個過期時間更早的所有文件。
/usr 用於存儲大量文件。最終用戶應用程序(從編輯器、游戲和接口,到系統特性)都位於其中,它是 man 頁面和其他更多內容的存儲庫。有些文件很有價值,但並不是系統操作所必須的,那麼您很可能會在 /usr 中找到它。
/var 是“variable”的簡寫,它是用於存儲那些大小通常隨時間而增大的文件的存儲庫。可以在 /var 中找到郵箱、日志文件、打印機隊列和數據庫。通常可以將 Web 站點保存在 /var 中,因為 Web 站點可能會在一段時間後異常地累積大量的數據。
以上是一些最常見的目錄名,盡管某些 UNIX 版本之間存在細微的差異。(例如,在基於 FreeBSD® 的 Mac OS X 上,將包含用戶的 home 目錄的目錄命名為 /Users,而不是 /home。)
保持傳統
事實上,名稱 etc、bin、lib 和 man 在 UNIX 的文化中是如此根深蒂固,以至於在計算機中的其他地方使用相同的名稱來標注類似用途的目錄已經成為一種傳統。例如,如果您查看一位專家的 home 目錄,您很可能會在其中發現 bin 和 lib 目錄分別存儲個人應用程序以及腳本和個人庫。
UNIX 的命名約定:獲取更多關於 UNIX 的命名約定的信息,請參見附錄 A:選擇一個標准,任何標准部分。
同樣地,/usr/local 中通常包括 etc、bin、lib、和 man。在歷史上,曾將 /usr/local 用於存儲來自於您的站點或者僅與您的站點有密切關系的應用程序和數據。/usr/local/bin 目錄用於存儲本地添加的、新的程序,以及標准系統實用工具的本地修改版本。例如,您的系統管理員可能在 /usr/local/bin/perl 中提供了 Perl 的最新和最好的版本,同時保持 /usr/bin/perl 不變,以便進行引用,並且因為其他的核心實用工具可能仍然依賴於它。/usr/local/lib 目錄作為 /usr/local/bin 的補充。
/usr/local 目錄甚至可能是一個完全獨立的分區(甚至是通過網絡文件系統從 Network Attached Storage [NAS] 設備裝入的分區),這使得可以更容易地對系統進行數據恢復和恢復使用。如果系統中發生了某種情況,管理員可以覆蓋操作系統的文件,而無需擔心會破壞本地數據。
甚至安裝包也是用了類似的目錄結構。例如 MySQL:如果使用了選項 --prefix=/usr/local/mysql, 進行配置,那麼它將在 /usr/local 中創建它自己的根目錄,名為 /usr/local/mysql,並創建子目錄 /usr/local/mysql/bin、/usr/local/mysql/lib 等等:
$ ls -1 /usr/local/mysql
bin/
configure*
data/
docs/
include/
lib/
man/
...
或者,如果您希望將 MySQL 的內容安裝到 /usr/local/bin、/usr/local/lib 和其他地方,可以使用 --prefix=/usr/local。
其他有趣的內容
因為本文只是簡要地介紹,所以讓我們再安排一些其他有趣的內容。
/etc
/etc 目錄是尋找配置文件的地方,這些配置文件通常以後綴 .conf 作為結束。一個較大的包可能擁有它自己的子目錄,以便收集用於這個包的所有配置文件。Apache 是一個很好的例子;特別是,Apache V2.2 已經重新組織了它的配置文件,使其更具模塊化,並具有更少的獨立性。 ---http://www.bianceng.cn
另一個新穎的內容是 /etc/init.d,其中包含當您的系統啟動時運行的許多啟動腳本。如果您希望干淨地重新啟動一個守護進程,例如,在更改它的配置之後,可以在 /etc/init.d 中查找同名的腳本。例如,要重新啟動 Postfix 郵件傳送代理(MTA),您可以運行:
$ /etc/init.d/postfix restart
/etc/init.d 還包含切換到單用戶模式的腳本,以便重新啟動並關閉計算機,並禁止登錄。
/var/spool
如前所述,/var 保存了那些大小可能隨時間增大和縮小的文件。與 / 一樣,可以將 /var 劃分為若干個子目錄,每個子目錄都有其自身的方案:
/var/spool/mail 是尋找您和其他用戶的傳入郵件的地方。您的郵箱是一個簡單的平面(連續的、非索引的)文件(除非您的系統管理員正在使用 maildir 格式)。傳入郵件追加到文件的尾部。您所丟棄的郵件將從該文件中刪除;並且當您讀取一條新的消息時,將會更改並重寫已有的消息狀態字段。您可以讀寫您自己的郵箱,但是可以通過權限防止您訪問其他用戶的郵箱。(建議您不要直接編輯您的郵箱。)
/var/log 保存了一套系統日志文件,或者記錄系統活動的文件。這些日志記錄了所有的活動,從郵件通信到失敗的登錄嘗試。通常,每個守護進程都擁有自己的日志文件,這使得當一個服務失敗時很容易搜尋所發生的問題。因為可以顯示系統活動,所以對日志文件的訪問通常會受到限制,只有超級用戶才可以訪問。
如果您的系統提供了集中的傳真服務,那麼 /var/spool 還將對這些請求進行排隊。
/usr/man
用於您的 UNIX 系統的核心 man 頁面位於 /usr/man 中。還可以在 /usr/local/man 和包的 man 目錄(如 /usr/local/mysql5/man)中找到 man 頁面的擴展集合。
因為 man 頁面可能像可執行文件那樣存放於許多不同的地方,所以 man 程序支持與 PATH 工作方式相同的環境變量 MANPATH。要在多個位置搜索一個特定的頁面,可以將 MANPATH 定義為一系列 man 頁面目錄:
MANPATH="/usr/man"
MANPATH="/usr/local/man:$MANPATH"
MANPATH="/usr/local/mysql/man:$MANPATH
MANPATH="$HOME/man:$MANPATH"
export MANPATH
在該示例中,首先 搜索 $HOME/man(它在最左邊,或者最前面),隨後是 /usr/local/mysql/man,依此類推。順便說一下,可以將上面的前四個命令簡化為下面的語句:
MANPATH="/usr/man:/usr/local/man:
/usr/local/mysql/man:$HOME/man"
然而,將附加的目錄隔離開來,將允許您快速地對條目進行重新排序,並輕松地添加新的目錄。而且,如果存在許多路徑,編輯後面的 MANPATH(通過擴展 PATH)變量將變得使人乏味。
包含文件
包含文件(或者頭文件)定義了在操作系統中或特定的庫中使用的常量、宏以及其他結構。不需要重新定義一個特定的結構,您只需要將頭文件“包含”在您的代碼(代碼重用的一種簡單形式)中,並按照頭文件中的規范編寫代碼。(man 中的第 2 部分和第 3 部分就專門用於這樣的規范;例如,可以嘗試 man 2 signal。) ---http://www.bianceng.cn
與 bin 和 lib 類似,include 是一個常見的目錄名。如果一個包提供了開發工具包,並且您已經將這個包安裝到了它自己的根目錄,那麼可以在 include 子目錄中找到相應的頭文件。
或者,如果您已經將包安裝到了公共的 /usr/local/{bin、lib、include} 目錄中,那麼可以在 /usr/local/include 中根據這個包進行命名的子目錄中找到包的頭文件。這是將所有的內容保存到一個公共地方的例外情況。為什麼呢?頭文件的命名不是唯一的,所以將所有的內容安裝到一個地方將會導致沖突,一個包有可能覆蓋另一個包的頭文件。
如果您從源代碼構建應用程序(您將在後面的部分中對其進行深入研究),並且頭文件位於一個非標准的位置,那麼您可能需要在編譯器命令中添加 -I 選項。作為一個示例,如果您的 ImageMagick 頭文件位於 /opt/include/magick 中,添加 -I/opt/include/magick 作為編譯器的開關。
非常深入地了解它
即將結束今天的 UNIX 旅行。現在,您可以更容易地穿越 UNIX 的小路和背街了。如果您迷路了,只需要說“家,家,家”(不要被 獵戶星座 所欺騙)或者輸入 cd 即可。請記住,您還可以使用 find 和 locate 來查找大多數文件,包括可執行文件、庫和包含文件。
下午好,女士們、先生們。下次旅行將在 30 天後啟程。
附錄 A:選擇一個標准,任何標准
您的 UNIX 操作系統附帶的軟件位於文件系統中適當的位置(可能存儲在 /bin 或者 /lib 中的),而本地添加的軟件則可能位於許多不同的位置。某些系統管理員將本地軟件放在 /usr/local 中,而其他的系統管理員則使用 /opt 或者“optional”,因為運行系統並不需要該軟件。而且,某些管理員會轉儲 /usr/local/bin 或 /opt/bin 中所有的可執行文件、/usr/local/lib 或 /opt/lib 中所有的庫,等等。
另一種方法(這是我更喜歡的范例)是為每一個本地添加的包創建一個根目錄,特別是在這個包很大的情況下。例如,我將 MySQL V5 安裝到 /usr/local/mysql5.0,將 Apache V2.2 安裝到 /usr/local/apache2.2。每個包的安裝程序都會在包的根目錄中創建它自己的 bin、lib 和 man 目錄。
這種方法有一個缺點,每個最終用戶必須向他或她的 PATH 環境變量中添加許多 bin 目錄。並且當這一需求並不是特別復雜時,通過在系統范圍的 Shell 啟動文件中擴展缺省的 PATH 設置,就可以解決這個問題。例如,Bash 系統范圍啟動腳本 /etc/profile,可能包含:
PATH="/bin:/usr/bin:/usr/local/bin"
PATH="$PATH:/usr/local/mysql5.0/bin"
PATH="$PATH:/usr/local/perl6/bin"
PATH="$PATH:/usr/local/Zend/bin"
export PATH
然而,將一個包存儲在它自己的“容器”中,這是很有好處的:
哪個包提供了特定的應用程序,這是顯而易見的。遵循這一分類系統,您可以使用 which 命令找到包的名字:
$ which mysql/usr/local/mysql5.0/bin/mysql
您可以同時保留同一個包的不同版本。
例如,如果您希望提供 Perl V5.6 和 Perl V5.8,可以將前者安裝到 /usr/local/perl5.6,將後者安裝到 /usr/local/perl5.8。每個用戶都可以通過改變 PATH 變量,來選擇一個 Perl 版本。 ---http://www.bianceng.cn
您可以同時保留不同的版本,但是可以通過使用符號鏈接,使得缺省情況下對應於某一個特定的版本。只需創建一個到您希望提供的包的版本的符號鏈接即可。
例如,假定您提供了前面介紹的兩個 Perl 版本。如果您希望將 Perl V5.8 作為缺省值,可以創建一個到 /usr/local/perl5.8 的符號鏈接,並將它命名為 perl:
$ ls -1 /usr/local/perl*perl5.6perl5.8$ sudo ln -s /usr/local/perl5.8
/usr/local/perl$ ls -1 -F /usr/local/perl*perl5.6/perl5.8/perl@
最終用戶現在可以添加 /usr/local/perl/bin 到他或她的 PATH 變量以運行 perl 命令。如果您最後需要或者希望切換到一個更新的或者更舊的 Perl 版本,那麼您只需刪除該符號鏈接,並重新創建一個指向不同目錄的符號鏈接即可。
對於這樣的維護任務,符號鏈接是非常重要的。您可以維護變量、變更路徑,並為方便訪問構建集合。例如,您可以在傳統的 /usr/local/bin 目錄中填入鏈接到其他包中的命令的符號鏈接,如 ln -s /usr/local/perl/bin/perl /usr/local/bin/perl。(是的,您可以創建指向另一個符號鏈接的符號鏈接。)