Subsections

2 深入檔案

現在您已經知道關於檔案的基本知識,該學些更加深入的東西了。


1 檔案的本質:硬連接和資料結點 (Hard Links and Inodes)

系統中的每個檔案是以資料結點 (inode: Information Node; 發音 ``eye-node'') 表示的,一個資料結點含有一個檔案的所有資訊。但是,資料結點不能直接看到,每個資料結點通過一個或多個的硬連接跟檔案系統聯繫起來。硬連接含有一個檔案的名稱和資料結點序號 (inode number)。而資料結點含有那個檔案本身,就是檔案在磁片上儲存的位置,它的訪問權限,檔案的類型等等。如果一個資料結點有它的資料結點序號 (inode number),那麼系統總能把它找到。

一個檔案可以有超過一個的硬連接,就是說多個不同的檔案名稱可以指向同一個檔案(它們都和同一個資料結點需要結合)。但您不能做跨越檔案系統的硬連接:所有的對某一個檔案(資料結點)做直接參考必需在同一個檔案系統上,這是因為每個檔案系統都有它自己的一套資料結點,不同的檔案系統間的資料結點序號可能會重複。

因為所有指向同一個資料結點的硬連接都是參照同一個檔案,您可以用一個檔案名稱來修改一個檔案,用指向同一個資料結點但使用一個不同的檔案名稱來查看您的更改結果。試一下這個:

cd; echo "hello" > firstlink
cd 到您的家目錄,建立一個有單詞 ``hello'' 的叫 firstlink 的檔案,您實際上是把 echo 命令的輸出重新定向,把輸出放到 firstlink �堙Aecho 命令僅僅重複您傳給它的任何東西。細節請參考有關 shell 的章節。

cat firstlink
確定檔案 firstlink 的內容。

ln firstlink secondlink
建立一個硬連接:secondlink 現在指向和 firstlink 相同的資料結點。

cat secondlink
確定 secondlink 的內容和 firstlink 一樣。

ls -l
注意列出的 firstlink 和 secondlink 檔案的資料結點聯合的硬連接數目是 2。

echo "change" >> secondlink
這個另外一個 shell 重新定向訣竅(現在不用考慮細節部分)。您實際上是把單詞 ``change'' 附加在 secondlink 的最後。可以用 cat secondlink 來確定。

cat firstlink
firstlink 現在後面也有了單詞 ``change''!這是因為 firstlink 和 secondlink 指的是同一個檔案。當您修改它的時候,它叫什麼名字是沒有關係的。

chmod a+rwx firstlink
改變檔案 firstlink 的訪問權限。鍵入命令 ls -l 以確定檔案 secondlink 的訪問權限也被改變了,這說明訪問權限的資料是存在資料結點�埵茪ㄛO硬連接�堛滿C

rm firstlink
刪除這個連接,這是 rm 命令的微妙之處:它實際上刪除的是連接而不是真正的檔案。現在鍵入 ls -l,您會看到 secondlink 還在。注意現在 secondlink 的硬連接數降到了 1 個。

rm secondlink
刪除另外一個連接。當一個檔案沒有任何連接的時候,Linux 本身會刪除真正的檔案,即它的資料結點。

所有的檔案都是這樣的──即使是像設備檔案這樣的特殊檔案(例如 /dev/hda)。

一個目錄只是一個檔案名稱和資料結點序號的列表,也就是說是一個硬連接的列表。當您建立一個硬連接時,您只是在一個目錄上加入了一個「檔名─序號」對。當您刪除一個檔案,您只是從目錄中刪除了一個硬連接。


2 檔案類型

到目前為止,我們隱藏了一個細節:Linux 核心把所有東西都看成是一個檔案。這包括目錄和各種設備,它們只是一些特殊的檔案罷了。

您可能記得,ls -l 顯示的第一個字符代表的是該檔案的類型,對於一個普通的檔案來說,這個字符就是個簡單的 -。其它可能的字符包括一下:

d
目錄 (directory)
l
符號連接 (symbolic link)
b
塊設備 (block device)
c
字符設備 (character device)
p
具名管道 (named pipe)
s
套接口 (socket)


1 符號連接 (Symbolic Links)

符號連接(也叫 ``symlinks'' 或軟連接 ``soft links'')是除硬連接以外的另外一種連接。一個符號連接是個特殊的檔案,它「指向」任意一個加載了的檔案系統上的一個硬連接。當您讀取一個符號連接的內容時,它給出它所指向的檔案的內容而不是這個符號連接本身的內容。因為目錄,設備,以及其它的符號連接都是各種類型的檔案,所以您可以使用一個符號連接指向所有這些檔案。

因此一個硬連接是一個檔案名稱和一個資料結點序號。一個檔案其實是一個資料結點:在磁片上的地址,檔案類型,允許模式等等。一個符號連接是一個資料結點,它的內容包含一個硬連接的名字。一個符號連接把一個檔案名稱和另外一個檔案名稱配對,而一個硬連接把一個檔案名稱和一個資料結點配對。

所有的指向同一個檔案的硬連接有相同的形態,就是說任何一個跟其他的都是一樣的,如果您在其中一個上面進行操作,其效果跟再其它的連接上進行操作是一樣的。而在符號連接上的操作,有時候會影響這個符號連接自己的資料結點(含有硬連接名字的那個結點)的資料,有時候影響的是它指向的那個硬連接的內容。

符號連接和硬連接之間有幾個重要的分別。

符號連接可以跨越檔案系統,因為它們含有從根目錄開始的完整的檔案名稱,而所有的完整的檔案名稱都是唯一的。但硬連接指向的是資料結點序號,資料結點序號僅僅在一個檔案系統內是唯一的,如果不知道檔案系統,則這個序號就會不明確。

您可以建立目錄的符號連接,但不能建立目錄的硬連接。每個目錄都有它的硬連接──在它的母目錄中以 . 列出,在它的所有子目錄中以 .. 列出──但為了在檔案系統中強制次序,不允許有其它的目錄硬連接存在。因而一個目錄中的檔案數目等於該目錄的所有硬連接的數目減 2 (減去目錄名和 . 連接)。比較符號連接和硬連接,您只能跟一個存在的檔案建立硬連接,因為它必需指向一個資料結點序號,但您可以把符號連接連到任何檔案名稱,不論這個檔案名稱的檔案是否存在。

刪除一個符號連接只刪除這個連接,這對於連到的那個目標檔案沒有影響,而刪除一個檔案的最後的那個硬連接,則會把那個檔案完全刪除。

範例:

cd; ln -s /tmp/me MyTmp
cd 到您的家目錄,命令 ln 的 -s 選項建立一個符號連接。這�堳堨萿漪O一個叫 MyTmp 的檔案指向檔案名稱 /tmp/me。

ls -l MyTmp
輸出結果應該類似:

lrwxrwxrwx 1 havoc havoc 7 Dec 6 12:50 MyTmp -> /tmp/me 
當然日期和用戶/群體名在您的系統上是不一樣的。注意檔案類別是 l,指示著這是一個符號連接,另外注意它的許可狀態:符號連接的許可狀態總是這樣的。如果您嘗試改變一個符號連接的狀態(使用 chmod 命令),您改變的是它所指向的那個檔案的狀態。

chmod 700 MyTmp
您會得到 No such file or directory(沒有這個檔案或目錄)的錯誤訊息,這是因為檔案 /tmp/me 並不存在,雖然您仍然可以就這麼建立一個符號連接。

mkdir /tmp/me
建立目錄 /tmp/me。

chmod 700 MyTmp
這個命令現在應該可以成功。

touch MyTmp/myfile
在 MyTmp 下建立一個檔案。

ls /tmp/me
這個檔案其實是在目錄 /tmp/me 下建立的。

rm MyTmp
刪除這個符號連接,主要這只刪除了連接,而不是那個它指向的目錄,所以使用的是 rm 而不是 rmdir(rmdir 用來刪除目錄)。

rm /tmp/me/myfile; rmdir /tmp/me
現在您自己清掃一下。

2 設備檔案 (Device Files)

設備檔案指向您的系統�堛漯垓z設備或者虛擬設備,例如您的硬碟、顯卡、螢幕和鍵盤。虛擬設備則包括控制台 (console),以 /dev/console 來表示。

設備分為兩種:字符式 (character) 和塊式 (block)。字符設備可以每次訪問一個字符,記住從這種設備中可以讀取和寫入的最小單位是一個字符(一個位元組)。

塊設備的存取必需以一個大的單位進行,我們叫作‘塊’。一塊�堨]含了一些字符。硬碟就是一個塊設備。

您可以像對其它檔案一樣對設備檔案進行讀寫,不過這些設備檔案�堨i能含有一些您根本看不懂的亂七八糟的東西。一般來說往這些檔案�媕H便寫入資料不是什麼好事兒,但又是卻會有用,例如,您可以把一個 postscript 檔案直接傾倒進列表機設備檔案 /dev/lp0 或者把一些調制解調器 (modem) 指令傳給相應的串連埠的設備檔案。

1 /dev/null

/dev/null 是一個特殊的設備檔案,您寫入它的任何東西都會被丟棄。如果您不想要什麼了,把它扔進 /dev/null。它基本上就是個無底深淵,如果您從 /dev/null �媗炊J,您立刻會得到一個檔案結束 (EOF : end-of-file) 字符。/dev/zero 是另一個類似的設備檔案,只是如果您從這�媗爸�,您得到的是一個 \0 字符(這是一個空 (null) 字符,代表什麼也不是,與數字 0 是不同的)。

3 具名管道 (Named Pipes, FIFOs)

一個管道是一個作用象個管道的檔案。您放東西進這個檔案,您放的東西從檔案的另一端出來,因此它也叫 FIFO(First-In-First-Out 縮寫,即先入先出),您放進去的第一個東西也是最先從另外一端出來的那個。

如果對一個具名的管道進行寫入,這個寫入的進程不到所有寫入的資料被從管道中都讀走了是不會結束的。如果您從一個管道中讀取,讀取進程會一直等到讀到一些東西以後才結束。管道的大小總是 0:它不儲存任何資料,它只是把兩個進程連接起來,就像 shell �堛� | 一樣。但是因為這個管道是有名字的,所以那兩個被連的進程不需要總同一個命令行出現,它們甚至不需要是屬於同一個用戶的。

您可以試一下這個例子:

cd; mkfifo mypipe
做一個管道。

echo "hello" > mypipe &
用 echo 把 ``hello'' 寫入管道 mypipe,同時把這個進程放到背景。注意這個進程在背景並不返回,因為它在等待有人從它的管道把資料讀出。

cat mypipe
這時候,echo 的進程將會返回,因為 cat 把管道�堛爾禤く�讀了,而 cat 命令會印出單詞 hello。

rm mypipe
您可以用一般方式刪除這個管道。

4 套接口 (Sockets)

套接口 (sockets) 類似於管道 (pipes) 但它是在網路上面工作的。您到電腦就是靠它來做網路處理的。您可能聽說過 ``Winsock'',那是 Windows 的套接口。

我們在這�堣ㄡ`入談有關套接口,因為如果您不寫程式,您不會用到它,但如果您看到您系統�埵陪蚗仵袓�型是 s,您知道它是什麼就行了。

3 proc 檔案系統 (The proc Filesystem)

Linux 的核心會建立一個特別的檔案系統,在 Debian 系統上,這個檔案系統加載於 /proc 目錄下。這是一個「偽檔案系統」 (``pseudo-filesystem''),因為它不在任何一個物理設備上。

proc 檔案系統包含系統和執行中的進程的資料。/proc 下的「檔案」,有些是可以讀懂的簡單文字格式(試著鍵入 cat /proc/meminfo 或 cat /proc/cpuinfo),另外一些是一些神秘的數字組合。系統會有一些工具可以讀取這些資料,然後翻譯成一些您看的懂的東西。

有些人當看到一個特別的檔案時常會覺得緊張,就是 /proc/kcore 檔案。這個檔案一般來說都很大,它是用來對核心進行除錯用的。它其實根本不存在您的物理設備�堙]記住 /proc 下是一個偽檔案系統),所以用不著擔心它的大小。

如果您想知道所有關於 /proc 的資料,參看它的手冊,鍵入man 5 proc。

4 大規模複製

有時候您會要把一個目錄複製 (copy) 到另外一個地方,可能是因為您加了一個新硬碟,您要把您的 /usr/local 複製到它上面。有幾個方法都可以達到這個目的。

第一個是用複製命令 cp。命令 cp -a 告訴 cp 在複製的時候,盡量保存可能保存的資料(這個 a 有 all 的意思)。因此,您可以用

cp -a /usr/local /destination
但是有些東西即使 cp -a 也不能保存下來[*]。因此,進行大規模複製工作的最好方法是使用兩個連在一起的 tar 命令,像是:
tar -cSpf - /usr/local | tar -xvSpf - -C /destination
第一個 tar 命令會把想要的目錄歸檔,然後通過管道把它送給第二個 tar 命令。第二個命令把歸好的檔解開,放到 -C 所指定的目的地。

John Goerzen / Ossama Othman / Debian 中文計劃