UNIX文件和目錄筆記

        這篇文章是我自己學習UNIX高級環境編程第四章文件和目錄的讀書筆記,主要內容是羅列一下本章主要的函數,因爲我還是新手,所以有很多知識都理解得不夠深刻,如果寫得有不對的地方,還希望網友們指證,好了,閒話不多說,開始我們的正題。

文件和目錄都是圍繞stat函數展開的。首先我們來看看stat函數的原型

    int stat(const char *restrict pathname,struct stat *restrict buf)

一旦給出了pathname,該函數就返回與此命名文件相關的信息,函數會填寫一個buf指向的結構,那這個結構有些什麼信息呢?我們來看一下這個結構的原型

      struct stat  {

          mode_t     st_mode; //文件類型

        info_t       st_ino;    //i節點編號

dev_ts t_dev; //設備號

nlink_t st_nlink; //文件鏈接數

uid_t  st_uid; //文件所以者的用戶ID

gid_t st_gid; //文件所有者所在的組ID

off_t st_size; //文件大小,單位爲bytes

time_t st_atime; //文件最後訪問時間

time_t st_mtime; //文件最後修改時間

time_t st_ctime; //文件狀態修改的最後時間

blksize_t st_blksize; //最合適的I/O塊大小

blkcnt_t  st_block; //磁盤所分配的塊的數量

}

我當時都看得頭暈眼花了,反正大家理解就是這是一個結構體,裏面有很多關於文件的信息,然後對於這個結構體裏面的信息,UNIX提供了很多函數以供對這個結構體的成員變量進行修改,下面我們展開看一下這些修改成員變量的函數吧。

一、文件類型

1、文件分類,這個不用多說,羅列一下就行,UNIX提供了以下七種文件,普通文件,目錄文件,字符特殊文件,塊特殊文件,管道或者FIFO,符號鏈接,套接字文件。

2、文件權限,這是這章的重中之重,可以說掌握了文件權限,你對文件系統的認識會加深很多,那和我一起來理清一下這裏面的具體細節吧。

  首先我們得把一大堆該死的概念弄清楚,直接從鳥哥書上搞了個圖,上圖比啥都清楚

大家看到了吧,所謂權限就是這麼回事,“王大毛家”和“張小豬家”就是組ID,王大毛,王二毛,王三毛就是用戶ID,至於那個萬能的天神,就是root,我們可以忽略它。

就這個圖而言我們要理解以下幾點:

1.王大毛和王二毛雖然同屬一個組,但是他們還是可以設置自己的權限,意思是說,他們都有各自的房間,如果王大毛去找二毛,得先敲敲門,不然是沒法進的;當然他們共享客廳,只要是王大毛家這個組。舉個例子加深一下理解:

王大毛設置權限如下:- |r w x| r - x| - - -。意思是自己對自己所有的東西都有使用權,讀寫執行,組裏面的其它成員有讀和執行權限,也就是所其它兩個人可以進他的房間,可以玩兒他的電腦啥的,但是不能在他的房間牆上亂畫啥的。對於張小豬,他不能進王大毛家,反正就是和大毛事沒得交集的。

2.一些枯燥的理論知識:

實際用戶ID和實際組ID:標識的是我們究竟是誰,這兩個字段在登錄時有用,在會話期間保持不變;

有效用戶ID和有效組ID:決定了我們的文件訪問權限。這兩個ID是可以設置的。通常設置爲實際ID號。

最直觀的例子就是用戶改密碼,我們知道,UNIX密碼文件在/etc/shadow文件中,普通用戶時不能寫入的,那我們怎麼修改自己的口令呢?原理如下,當用戶運行時,將有效ID設置爲root之類,這個時候該用戶就有了超級管理員權限,就可以修改密碼啦。。。。

設置用戶ID和設置組ID:這玩意兒就是有效用戶ID和有效組ID的副本。

3.目錄的執行權限,這個一度困擾我很久,我以前天真的認爲,只要對目錄有讀權限,那我們就可以在目錄裏面爲所欲爲了啥,UNIX可不這麼幹,還給我增加了個執行權限,其實說白了就是:當有目錄讀權限時,你是可以看目錄下有什麼文件或者子目錄,但是你想進去目錄繼續訪問,那你必須得先得有執行權限才行。平常生活中是不是有很多例子嘛,看馬戲,會給你露一個小縫,給你看看都有些啥子,要進去舒舒服服的看,那對不起,先買票,這個票就是執行權限的意思哦。

4.新文件和目錄的所有權:新文件的用戶ID就是當前用戶的有效ID,組ID就是它所在的目錄的組ID,意思就是說,這個組ID興許不是當前進程的組ID。比如王大毛成家了,家裏出生了個小孩,當然這個小孩子的用戶ID肯定就是他父親了啥,跟着他父親姓嘛,但是他小孩兒不一定會在他這家長大啥,因爲王大毛買了個新房子,這個小孩的組ID就是那個新家了啥。。大概是這個意思,我都有點糊塗了,呵呵。

通過以上幾點的闡述,再去看書上的這種ID那種ID就輕鬆得多了哦。。。。。。

二、文件系統:

同樣採取同樣的方法,來細分一下,理解幾個關鍵的概念。

1、目錄:目錄是幹啥的,比如書的目錄,或者說windows系統的目錄,目錄是一種文件,通俗點說其實就是一個路徑啦,目錄可以有子目錄,在UNIX裏邊,子目錄稱呼爲目錄項,目錄下面可以有文件,這點倒是很容易理解的。

2、目錄項:目錄項的內容也不復雜,一個目錄項主要包括了文件名和索引節點(i節點)號,索引節點號是指向索引節點表( system inode table )中對應的索引節點的

3.i節點:i節點就是實際指向一個文件的東東,主要就是文件的屬性,包括鏈接數、文件所有者、文件建立和修改的時間,文件在磁盤的位置,文件大小、使用權限等等。

總結一下,就是說,目錄文件包含目錄項,目錄項又可以包含文件。

4.硬鏈接和符號鏈接:這個我就從網上copy的一個博文了哈,感謝那個偉大的博主,讓我理解得很是深刻:

【硬連接】
硬連接指通過索引節點來進行連接。在Linux的文件系統中,保存在磁盤分區中的文件不管是什麼類型都給它分配一個編號,稱爲索引節點號(Inode Index)。在Linux中,多個文件名指向同一索引節點是存在的。一般這種連接就是硬連接。硬連接的作用是允許一個文件擁有多個有效路徑名,這樣用戶就可以建立硬連接到重要文件,以防止“誤刪”的功能。其原因如上所述,因爲對應該目錄的索引節點有一個以上的連接。只刪除一個連接並不影響索引節點本身和其它的連接,只有當最後一個連接被刪除後,文件的數據塊及目錄的連接纔會被釋放。也就是說,文件真正刪除的條件是與之相關的所有硬連接文件均被刪除。

【軟連接】
另外一種連接稱之爲符號連接(Symbolic Link),也叫軟連接。軟鏈接文件有類似於Windows的快捷方式。它實際上是一個特殊的文件。在符號連接中,文件實際上是一個文本文件,其中包含的有另一文件的位置信息。

2.通過實驗加深理解
[oracle@Linux]$ touch f1          #創建一個測試文件f1
[oracle@Linux]$ ln f1 f2          #創建f1的一個硬連接文件f2
[oracle@Linux]$ ln -s f1 f3       #創建f1的一個符號連接文件f3
[oracle@Linux]$ ls -li            # -i參數顯示文件的inode節點信息
total 0
9797648 -rw-r--r--  2 oracle oinstall 0 Apr 21 08:11 f1
9797648 -rw-r--r--  2 oracle oinstall 0 Apr 21 08:11 f2
9797649 lrwxrwxrwx  1 oracle oinstall 2 Apr 21 08:11 f3 -> f1

從上面的結果中可以看出,硬連接文件f2與原文件f1的inode節點相同,均爲9797648,然而符號連接文件的inode節點不同。

[oracle@Linux]$ echo "I am f1 file" >>f1
[oracle@Linux]$ cat f1
I am f1 file
[oracle@Linux]$ cat f2
I am f1 file
[oracle@Linux]$ cat f3
I am f1 file
[oracle@Linux]$ rm -f f1
[oracle@Linux]$ cat f2
I am f1 file
[oracle@Linux]$ cat f3
cat: f3: No such file or directory

通過上面的測試可以看出:當刪除原始文件f1後,硬連接f2不受影響,但是符號連接f1文件無效

3.總結
依此您可以做一些相關的測試,可以得到以下全部結論:
1).刪除符號連接f3,對f1,f2無影響;
2).刪除硬連接f2,對f1,f3也無影響;
3).刪除原文件f1,對硬連接f2沒有影響,導致符號連接f3失效;
4).同時刪除原文件f1,硬連接f2,整個文件會真正的被刪除。

三、文件時間以及其它零碎知識點

文件時間分爲:文件數據最後訪問時間,文件數據最後修改時間,i節點狀態的最後更改時間。

修改時間和更改狀態時間之間的區別:修改時間是文件內容最後一次修改時間,更改狀態時間是該文件i節點最後一次修改的時間,i節點修改比如權限,用戶ID,鏈接數等,他們並沒有改變文件的實際內容

至於後面的設備啥的,就比較雞肋了,也沒仔細看過,所以就不做闡述了。

文章最後我來羅列一下對於文件和目錄操作的函數,以便大家查閱:

access函數:按照實際用戶ID和實際組ID進行訪問權限的測試;

設置文件權限:

umask函數:mode_t umask(mode_t cmask);創建文件的屏蔽字,也就是文件的訪問權限;

更改文件權限:

int chmod(const char* pathname,mode_t mode);在指定的文件上操作

int fchmod(int filedes,mode_t mode);在已經打開的文件上操作

int chown(const char* pathname,uid_t owner,gid_t group);

int fchown(int fileds,uid_t owner,gid_t group);

int lchown(const char* pathname,uid_t owner,gid_t group);

文件鏈接:

硬鏈接:

int link(const char* existingpath,const char *newpath);創建一個目錄項newpath,引用現有文件existingpath。如果newpath存在,則出錯。如果說是創建目錄的硬鏈接,只有超級用戶有資格

int unlink(const char* pathname);刪除一個現有的目錄項。如果刪除之後,其文件鏈接數不爲0,那麼仍然可以通過其他鏈接訪問該目錄

符號鏈接:

int symlink(const char* actualpath,const char* sympath);//不要求sympath存在,也不要求兩個變量在同一個文件系統中

ssize_t readlink(const char* restrict pathname,char* restrict buf,size_t bufsize);//打開符號鏈接,讀取該鏈接中的名字

更改文件時間:

int utime(const char* pathname,const struct utmibuf* times);//times爲空指針,則將時間修改爲當前時間,不爲空,則設置爲time指向的時間

目錄操作

int mkdir(const char* pathname,mode_t mode);//創建空目錄,中.和..目錄項是自動創建的。

int rmdir(const char* pathname);//刪除一個空目錄。

int chdir(const char* pathname);//更改當前工作目錄

int fchdir(int fildes);

好了,以上就是我看書的一些筆記,當然這其中省略了很多細節,但是我覺得從宏觀把握更爲重要,因爲細節總是那麼多那麼詳細,憑記憶力是無法記住這麼多東西,我更贊同的是,理解UNIX對於文件的管理的大方向,然後把UNIX環境編程作爲一本工具書,不會的去看看查查,瞭解其中的一些細節,這樣或許學習效率要高很多。如果有寫的不對的地方,希望網友們指證批評,謝謝。








 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章