Linux文件基本知識
2024-09-05 23:01:05
供稿:網友
Linux
文件基本知識
磁針石
聯系方式: gmail
and gtalk: xurongzhong#gmail.com
文件路徑:D:/blog/@Linux/linux
基礎/文件系統
參考資料
* 《深入理解Linux內核(第三版)》之1.5. An Overview of the Unix
Filesystem
* 《LINUX與UNIX
SHELL編程指南》第一章
2008-10-10 根據參考資料1,2創建初稿。
文件類型
Unix 文件可以是下列類型之一 :
• 普通文件(regular file)
• 目錄
• 符號鏈接
• 面向塊的設備文件(block-oriented device file)
• 面向字符的設備文件(character-oriented device file)
• 管道(pipe)和命名管道(named pipe)(也叫FIFO)
• 套接字(socket)
前三種文件類型是所有Unix 文件系統的基本類型。設備文件與I/O
設備以及集成到內核中的設備驅動程序相關。例如,當程序訪問設備文件時,它直接訪問與那個文件相關的I/O 設備。管道和套接字是用于進程間通信的特殊文件。
文件描述符與索引節點
Unix對文件的內容和描述文件的信息給出了清楚的區分。除了設備文件和特殊文件系統文件外,每個文件都由字符序列組成。文件內容不包含任何控制信息,如文件長度或文件結束(end-of-file,EOF)符。
文件系統處理文件需要的所有信息包含在一個名為索引節點(inode)的數據結構中。每個文件都有自己的索引節點,文件系統用索引節點來標識文件。
雖然文件系統及內核函數對索引節點的處理可能隨Unix系統的不同有很大的差異,但它們必須至少提供在POSIX 標準中指定的如下屬性:
• 文件類型
• 與文件相關的硬鏈接個數
• 以字節為單位的文件長度
• 設備標識符(即包含文件的設備的標識符)
• 在文件系統中標識文件的索引節點號
• 文件擁有者的UID
• 文件的用戶組ID
• 幾個時間戳,表示索引節點狀態改變的時間、最后訪問時間及最后修改時間
• 訪問權限和文件模式
另有文件的位置。
訪問權限和文件模式
文件的潛在用戶分為三種類型:
• 作為文件所有者的用戶
• 同組用戶,不包括所有者
• 所有剩下的用戶(其他)
有三種類型的訪問權限——讀、寫及執行每組用戶都有這三種權限。因此,文件訪問權限的組合就用九種不同的二進制來標記。還有三種附加的標記,即suid (Set User ID), sgid (Set Group ID),及sticky 用來定義文件的模式。當這些標記應用到可執行文件時有如下含義:
suid
進程執行一個文件時通常保持進程擁有者的UID。然而,如果設置了可執行文件
suid 的標志位,進程就獲得了該文件擁有者的UID。
sgid
進程執行一個文件時保持進程組的用戶組ID。然而,如果設置了可執行文件sgid
的標志位,進程就獲得了該文件用戶組的ID。
sticky
設置了sticky 標志位的可執行文件相當于向內核發出一個請求,當程序執行結
束以后,依然將它保留在內存(這個標志已經過時,現在使用基于代碼頁共享的其他方法)。
當文件由一個進程創建時,文件擁有者的ID 就是該進程的UID。而其用戶組ID 可以是進程創建者的ID,也可以是父目錄的ID,這取決于父目錄sgid 標志位的值。
對于文件屬主來說,在只有讀權限位被置位的情況下,仍然可以通過文件重定向的方法向該文件寫入。能否刪除一個文件還依賴于該文件所在目錄權限位的設置。
hmod [who]
operator [permission] filename
who的含義是:
u 文件屬主權限。
g 同組用戶權限。
o 其他用戶權限。
operator的含義:
+ 增加權限。
- 取消權限。
= 設定權限。
permission的含義:
r 讀權限。
w 寫權限。
x 執行權限。
s 文件屬主和組set-ID。
t 粘性位*。
l 給文件加鎖,使其他用戶無法訪問。
u,g,o 針對文件屬主、同組用戶及其他用戶的操作。
*在列文件或目錄時,有時會遇到“
t”位。“t”代表了粘性位。如果在一個目錄上出現
“t”位,這就意味著該目錄中的文件只有其屬主才可以刪除,即使某個同組用戶具有和屬主
同等的權限。不過有的系統在這一規則上并不十分嚴格。
如果在文件列表時看到“ t”,那么這就意味著該腳本或程序在執行時會被放在交換區(虛
存)。不過s于當今的內存價格如此之低,大可不必理會文件的“ t”的使用。
還可以通過使用- R選項連同子目錄下的文件一起設置:
chmod -R 664 /usr/local/home/dave/*
這樣就可以一次將/usr/local/home/dave目錄下的所有文件連同各個子目錄下的文件的權限全部設置為文件屬主和同組用戶可讀和寫,其他用戶只讀。使用- R選項一定要謹慎,只有在需要改變目錄樹下全部文件權限時才可以使用。
目錄的讀權限位意味著可以列出其中的內容。寫權限位意味著可以在該目錄中創建文件,如果不希望其他用戶在你的目錄中創建文件,可以取消相應的寫權限位.
如果把同組用戶或其他用戶針對某一目錄的權限設置為--x,那么他們將無法列出該目錄中的文件。如果該目錄中有一個執行位置位的腳本或程序,只要用戶知道它的路徑和文件名,仍然可以執行它。用戶不能夠進入該目錄并不妨礙他的執行。
文件操作的系統調用
當用戶訪問一個普通文件或目錄文件的內容時,他實際上是訪問存儲在硬件塊設備上的一些數據。從這個意義上說,文件系統是硬盤分區物理組織的用戶級視圖。因為處于用戶態的進程不能直接與低層硬件交互,所以每個實際的文件操作必須在內核態下進行。因此,Unix 操作系統定義了幾個與文件操作有關的系統調用。
所有Unix內核都對硬件塊設備的處理效率給予極大關注,其目的是為了獲得非常好的系統整體性能。在后面的章節中,我們將描述Linux 與文件操作相關的主題,尤其是討論內核如何對文件相關的系統調用作出反應。為了理解這些內容,你需要知道如何使用文件操作的主要系統調用。下面對此給予描述。
*訪問打開的文件
對普通Unix 文件,可以順序地訪問,也可以隨機地訪問,而對設備文件和命名管道文件,通常只能順序地訪問。在這兩種訪問方式中,內核把文件指針存放在打開文件對象中,也就是說,當前位置就是下一次進行讀或寫操作的位置。
順序訪問是文件的默認訪問方式,即read()和 write()系統調用總是從文件指針的當前位置開始讀或寫。為了修改文件指針的值,必須在程序中顯式地調用lseek()系統調用。當打開文件時,內核讓文件指針指向文件的第一個字節(偏移量為0)。
lseek()系統調用需要下列參數:
newoffset=lseek(fd,
offset, whence);
其參數含義如下:
fd
表示打開文件的文件描述符。
offset
指定一個有符號整數值,用來計算文件指針的新位置。
whence
指定文件指針新位置的計算方式:可以是offset 加0,表示文件指針從文件頭移動;
也可以是offset 加文件指針的當前位置,表示文件指針從當前位置移動;還可以是
offset 加文件最后一個字節的位置,表示文件指針從文件末尾開始移動。
read()系統調用需要以下參數:
nread= read(fd,
buf, count);
其參數含義如下:
fd
表示打開文件的文件描述符。
buf
指定在進程地址空間中緩沖區的地址,所讀的數據就放在這個緩沖區。
count
表示所讀的字節數。
當處理這樣的系統調用時,內核會嘗試從擁有文件描述符fd的文件中讀count個字節,其起始位置為打開文件的offset 字段的當前值。在某些情況下可能遇到文件結束、空管道等等,因此內核無法成功地讀出全部count 個字節。返回的nread 值就是實際所讀的字節數。給原來的值加上nread 就會更新文件指針。write()的參數與read()相似。
*關閉文件
當進程無需再訪問文件的內容時,就調用系統調用:
res=close(fd);
釋放與文件描述符fd 相對應的打開文件對象。當一個進程終止時,內核會關閉其所有仍然打開著的文件。*更名及刪除文件
要重新命名或刪除一個文件時,進程不需要打開它。實際上,這樣的操作并沒有對這個文件的內容起作用,而是對一個或多個目錄的內容起作用。例如,系統調用:
res= rename(oldpath, newpath);
改變了文件鏈接的名字,而系統調用:
res= unlink(pathname);
減少了文件鏈接數,刪除了相應的目錄項。只有當鏈接數為0 時,文件才被真正刪除。