由於以前學習Linux的時候沒有做比較全面的總結筆記,而且平時大部分工作都在windows上進行,所以關於Linux的一些知識點有所遺忘。近期難得空閑,翻閱書籍,學習《鳥哥的Linux私房菜》,重溫Linux知識,借此機會想把Linux的相關知識做一個總結筆記。首先要總結的是Linux文件相關知識——權限與屬性。注意,這不是Linux入門,這是學習筆記,入門推薦《鳥哥的Linux私房菜》,講得很詳細。
講解Linux文件的權限與屬性,自然繞不開ls命令啦。在Linux中,我們可以通過命令ll(即ls -l)查看當前目錄下文件的權限與屬性的詳情列表:
輸出結果中有7個信息列,從左到右分別是:文件類型+權限、文件連接數、文件屬主、文件屬組、文件大小、文件最后修改時間、文件名稱。好了,下面開始詳細介紹每個信息點。
一、文件權限
首先要介紹的是文件權限,這在Linux中是很重要的。
1. 基本權限:
Linux是一個多用戶的操作系統,對於每一個文件而言,用戶的類型有三種:文件屬主,即文件的創建者;文件屬組,即文件所屬的用戶群組;其他用戶。對應的,有三種用戶類型對於這個文件的權限,每種用戶類型的權限都有:讀(r)、寫(w)、執行(x)三種權限。在上面的截圖的第一列信息中有十個字符,其中第一個字符表示的是文件類型,后面的9個字符從左到右分別表示屬主、屬組和其他用戶對於文件的rwx三種權限的占位符,某個位置上有對應英文字母表示有相應權限,如果是“-”則表示沒有相應權限。例如,最后一個文件“yzz”,屬主和屬組用戶對文件有讀寫權限,而其他用戶則只有讀權限。
修改文件權限可以通過chmod指令來實現,其中權限可以通過字符表示也可以通過數字來表示,比較簡單,這里就不再過多說明,使用上圖“myfile”這個文件來實驗,直接看實驗截圖,注意觀察文件各個權限位的變化:
(u表示屬主,g表示屬組,o表示其他用戶)
如果想要修改文件屬主、屬組可以通過chown和chgrp來實現(注意觀察第三列和第四列信息的變化):
2. 特殊權限:
(1)Set UID:
當s這個標志出現在文件屬主的x權限位上時,此時就被稱為Set UID,簡稱為SUID的特殊權限。SUID的限制與功能如下:
<1>SUID權限僅對二進制程式有效;
<2>執行者對該程式需要具有x的可執行權限;
<3>本權限僅在執行該程式的過程中有效;
<4>執行者將具有該程式擁有者的權限。
以下面兩個文件舉例說明:
從上圖可以看出,一般用戶對於“/etc/shadow”這個文件是沒有任何權限的,只有root可以對這個文件進行修改。但是用戶卻可以使用passwd這個指令,也就是執行“/usr/bin/passwd”這個文件通過對“/etc/shadow”進行修改來修改自己的密碼。原因就是因為“/usr/bin/passwd”這個文件具有SUID的特殊權限,一般用戶執行這個文件的過程中暫時擁有這個文件的擁有者root的權限,所以也就可以對“/etc/shadow”這個文件進行修改了。
(2)Set GID:
當s這個標志出現在文件屬組的x權限位上時,稱為Set GID,簡稱SGID。SGID不僅對二進制程式有效,對於目錄也是有效的。
當SGID設置在二進制程式上時,與SUID類似地,文件的執行者在執行過程中將暫時擁有文件屬組的權限,這個在Linux中有以下兩個文件可作為例子:
當SGID設置在目錄上時,具有以下特殊功能:
<1>對目錄具有r與x權限的用戶能進入目錄。
<2>使用者在此目錄下的有效群組將會變成該目錄的群組。
<3>對目錄具有w權限的用戶,在此目錄下創建文件時,新文件的群組與此目錄群組相同。
當某個用戶組的用戶想要在某個目錄下共享資源的時候,SGID的第三個功能就能派上用場了。
(3)Sticky Bit:
Sticky Bit簡稱SBIT,目前只針對目錄有效。當某個目錄被設置了SBIT之后,目錄的其他用戶的x權限位將出現t標志,具有w和x權限的用戶在該目錄下創建的文件或目錄,只有自己和root才有權限刪除。/tmp就是這樣的目錄:
(4)SUID/SGID/SBIT設置:
特殊權限的設置也是使用chmod這個命令,特殊權限的表示同樣可以使用字符形式也可以使用數字,使用數字時在代表rwx基本權限三個數字前面再加一個數字就可以了,其中4為SUID,2為SGID,1為SBIT,設置實驗如下:
輸出結果最后一行,S、T為大寫時表示對應特殊權限為空,原因是對應用戶沒有x執行權限。
3. 默認權限:
在Linux中,新建的文件或目錄的默認權限是由umask決定的,那么這個umask到底是什么呢?我們先來查看一下:
這里有兩種查詢方式,第二種我們很容易明白,那第一種打印出來的那四個數字有什么意義呢?它們分別代表特殊權限(SUID/SGID/SBIT)、文件屬主(u)、文件屬組(g)、其他用戶(o)的權限!
那新建文件或目錄的默認權限是怎么計算的呢?我們知道新建文件默認是沒有執行權限的,所以它的完整權限是rw-rw-rw-,用數字表示就是666,而新建目錄默認是有執行權限的,所以它的完整權限是rwxrwxrwx,用數字表示就是777。新建文件或目錄的默認權限就是使用這個三位數字表示的完整權限分別減去umask指令查詢出來的后面三位數字,所以當umask是0002的時候,新建文件的默認權限就是664,即rw-rw-r--,新建文件夾的默認權限就是775,即rwxrwxr-x,也就是說umask -S打印出來的結果其實是新建目錄的默認權限,新建文件的默認權限要在umask -S結果的基礎上減去所有用戶的x執行權限。不信我們可以新建文件和目錄來看看結果:
(touch和mkdir指令分別用於創建空文件和空目錄)
果然,結果和我們計算的一樣!
如果你想修改默認權限,直接使用umask指令后面接上數字來執行即可:
4. ACL細部權限設定:
如果需要單獨設置某個用戶或某個群組對某個文件或某個目錄的權限,則需要使用ACL(Access Control List)進行細部權限設定。可以使用setfacl命令進行設置,使用getfacl命令進行查詢。
(1)查看當前系統是否支持ACL:
(2)設置單個用戶對某個文件的權限:
(若用戶名為空,則表示設置root用戶對文件的權限;若設定權限為“-”則表示無權限)
(3)設置某個群組對某個文件的權限:
(4)有效權限設置:
(用戶或群組所設定的權限必須要在umask的權限設定范圍內才會生效)
當使用以上命令給目錄設置權限的時候,所設置的ACL權限都是無法被該目錄下的子目錄和文件所繼承的,若想繼承,則需下達命令格式為——setfacl -m d:u:賬號:權限 目錄名稱。若在設置目錄的ACL權限時,希望連同目錄下的文件與子目錄也一起設置則使用命令——setfacl -R u:賬號:權限 目錄名稱。
設置ACL權限之后還可以移除,移除全部ACL權限使用指令——setfacl -b 文件名稱,移除某個賬號的ACL權限使用指令——setfacl -x u:賬號 文件名稱。
二、時間屬性
在Linux中,每個文件與目錄都有許多時間屬性,其中有三個主要的時間屬性:mtime(modification time)、atime(access time)、ctime(status time),分別表示文件內容最后修改時間、文件內容最后訪問時間、文件狀態(例如權限、屬性)最后改變時間。
ll(ls -l)命令默認展示的是mtime,我們可以通過指定--time選項來查看其它兩個時間屬性,而且默認展示的是簡寫的時間,我們可以通過指定--full-time選項來查看完整的時間:
(這里使用三個指令按順序分別展示了mtime、atime和ctime)
若想修改文件的時間屬性,可以使用touch指令,例如我們來修改上圖的“temp”文件的時間屬性(有多種選項參數,這里只展示-t選項的使用):
可以看到,文件的mtime和atime已經被我們改為-t選項指定的時間了,但是ctime並沒有,而是變成了我剛剛執行這個touch命令的時間。注意,ctime的意義是文件狀態的最后改變時間,這里的文件狀態包括權限、屬性等,我們剛才改變了文件的mtime和atime這兩個時間屬性,所以文件狀態的最后改變時間就是剛剛沒錯啊哈哈。注意,即使我們復制一個文件的時候復制了所有的屬性,也無法復制ctime這個屬性的!
三、連接數
ll(ls -l)這個命令打印出來的結果中第二列數據表示的就是文件的連接數了,那么什么是文件或目錄的連接數?它又是怎么計算出來的呢?這就要從硬連接和軟連接說起了。由於硬連接涉及到Linux文件系統結構的問題,尤其是inode和data block的概念,所以如果不了解的可以先參考一下我的另一篇博文——Linux的文件系統結構(以下對硬連接的講解是建立在讀者已經了解這方面知識的基礎上進行的)。
什么是硬連接呢?假設現在已有一個文件A,它的連接數是1,那么我們可以在某個目錄B下面建立文件A的硬連接C,這個建立硬連接的過程其實就是在目錄B的data block中添加一條“硬連接C的文件名到文件A的inode編號”的關聯記錄,僅此而已,並沒有真正創建新的文件。硬連接建立之后,就有兩個文件名指向文件A的inode了,分別是文件A和硬連接文件C,所以文件A的連接數就變成了2,也就是說ll命令中展示的連接數實際上表示的就是硬連接數,每建立多一個硬連接,連接數就會增加1。下面我們就使用ln這個命令來創建一個硬連接看看效果:
這里我們創建了文件myfile的硬連接myfile2,可以看到,myfile的連接數增加了1,而且這兩個文件的權限、屬性都是一模一樣的,這是因為文件的權限、屬性都是存儲在inode中的,而這兩個文件名指向的是同一個inode啊,它們的文件內容也會是相同的,實際上就是同一個文件來的。
那軟連接又是什么呢?軟連接其實就類似windows中的快捷方式。假設現在已有一個文件A,我們要在某個目錄中創建文件A的軟連接B,其實就是創建一個新的文件B,只是文件B的data block中僅僅記錄了文件A的路徑位置,打開文件B的時候就會讀取到文件A的位置然后打開文件A。我們可以通過ln -s來創建一個軟連接:
這里我們創建了文件myfile的軟連接myfile3,可以看到,軟連接對源文件的連接數並沒有影響的,myfile3的文件大小為6個字節,這是因為它記錄了源文件的名稱“myfile”,6個字符,剛好6個字節!
現在來總結一下硬連接與軟連接的異同點:
(1)都可以使用ln指令來創建,只是創建軟連接的時候要加上-s選項。
(2)打開硬連接和軟連接最終都是打開源文件。
(3)創建1個硬連接會使源文件的連接數增加1,而創建軟連接則不會。
(4)創建硬連接並不會創建新文件,而創建軟連接則會新建一個文件。
(5)源文件刪除之后,硬連接不會失效,而軟連接會失效。
(6)硬連接不能跨文件系統,不能連接目錄。
最后補充一點,關於目錄的連接數。我們新建一個空目錄的時候,目錄中默認就有“.”和“..”兩個子目錄,其中“.”目錄指向了當前目錄的inode,而“..”指向了上一層目錄的inode。所以當我們創建一個新的空目錄的時候,它的連接數是2,而上一層目錄的連接數會增加1。
四、隱藏屬性
文件的隱藏屬性主要是在系統安全方面起到作用,我們可以使用chattr命令來設置隱藏屬性,而使用lsattr來查詢。chattr指令的選項參數有很多,但比較常用的有兩個:a和i,這兩個屬性都是只有root才能設置的,設置a表示這個文件只能增加內容而不能刪除也不能修改,設置i表示文件不能被刪除、改名、創建連接,也無法添加內容和修改內容,反正就是不能做任何改動!下面是設置與查詢操作示例:
(+表示增加某個屬性,-表示減去某個屬性)
五、文件類型
回到本文第一個ll(ls -l)指令的截圖,ll指令打印的信息中第一列第一個字符表示的就是文件類型,不同的字符表示的文件類型不同:
-:普通文件(包括硬連接)。
d:目錄。
l:軟連接。
b:區塊設備文件。
c:字符設備文件。
s:資料接口文件(sockets)。
p:資料輸送文件(FIFO,pipe)。
可以使用file指令來查看某個文件具體的文件類型:
六、文件大小
ll(ls -l)指令輸出的第5列信息表示的就是文件大小,ll指令默認展示的文件大小都以byte(字節)為單位,可以使用-h參數將其展示成k、M、G為單位的形式:
其中total 16K表示這個目錄中所有文件大小總和。
然而我們會發現這些文件大小加起來並沒有達到16K這么多啊:4k+60bytes+15bytes+15bytes=4k+90bytes<16k,怎么回事呢?如果大家對Linux文件系統結構有所了解就會知道怎么回事了,同樣可以參考我的另一篇博文——Linux的文件系統結構。其實這里的16K表示的並不是所有文件真實大小的總和,而是所有文件占用磁盤空間的總和,我們知道即使一個文件很小,但它至少都會占用一個data block的。我們可以在ll指令添加-s選項查看各個文件占用的磁盤空間大小:
4k+4k+4k+4k=16k!是的,這里的第一列表示的就是每個文件占用的磁盤空間大小了,而第六列表示的則是每個文件內容的真實大小。從這里也可以看出我的Linux系統的每個data block大小為4K。
七、文件名稱
ll(ls -l)指令輸出的最后一列信息表示的就是文件名稱。其實文件名稱本身並沒有什么好說的,只是關於文件名稱引申出來的一些問題需要記錄一下。首先是隱藏文件問題,Linux的隱藏文件不像windows的隱藏文件那樣需要進行屬性設置的,它只是純粹根據文件名稱來決定文件是否隱藏,若文件名稱以“.”開頭則隱藏,否則顯示。默認情況下我們使用ls指令是查看不到這些隱藏文件的,可以加上-a選項來查看所有文件。
另外,Linux的文件也沒有什么所謂的后綴名。比如一個文件是否為執行文件,根本與它是什么后綴名沒關系,只是與文件的x執行權限有關罷了。不過我們可以在文件名后面加上一些適當的后綴名,使得我們能借此了解文件大概是什么內容的,只是這個后綴名沒有什么實際用處就是了。