Linux文件系統剖析

   文件系統是學習Linux的一個十分基礎的知識,同時也是學習Linux的一個必備知識。本文將站在“上帝視角”對整個文件系統進行進行詳細的講解,主要內容包括文件系統結構元素的組成、文件管理相關命令的使用以及軟連接和硬鏈接的介紹。


一、文件系統結構元素的組成

    大家都知道程序是由指令加數據組成。數據分爲元數據和數據。元數據用來存儲文件的屬性信息,保存在inode節點中,數據則保存在block中。而文件系統是對一個存儲設備上的數據和元數據進行組織的機制。

    linux系統文件系統通過使用一組通用的 API 函數,把幾乎所有的資源抽象爲文件的形式,即我們所說的“一切皆文件”。例如,read 函數調用可以從指定的文件描述符讀取一定數量的字節。read () 函數調用可以從指定的文件描述符讀取一定數量的字節。open() 函數調用可以從指定的文件描述符打開文件。write()函數調用可以在指定的文件描述符中寫入數據。close()函數調用可以關閉指定的文件。


1.文件系統目錄標準(FHS)

     Filesystem Hierarchy Standard(文件系統目錄標準)的縮寫,多數Linux版本採用這種文件組織形式,類似於Windows操作系統中c盤的文件目錄,FHS採用樹形結構組織文件。FHS定義了系統中每個區域的用途、所需要的最小構成的文件和目錄同時還給出了例外處理與矛盾處理。在Linux中,所有的文件與目錄都由根目錄/ 開始。那是所有目錄與文件的源頭。然後再一個一個分支下來,有點像樹狀。因此,我們也稱這種目錄配置方式爲:“目錄樹(directory tree)”。

[root@node1 ~]#tree -L 1 /
/
├── bin -> usr/bin
├── boot
├── dev
├── etc
├── home
├── lib -> usr/lib
├── lib64 -> usr/lib64
├── media
├── mnt
├── opt
├── proc
├── root
├── run
├── sbin -> usr/sbin
├── srv
├── sys
├── tmp
├── usr
├── var
└── web

這個目錄樹主要特性有:

    目錄樹的起始點爲根目錄(/, root)。

    每一個目錄不僅能使用本地端分區的文件系統,也可以使用網絡上的文件系統。舉例來說,可以利用網絡文件系統(Network File System,NFS)服務器載入某特定目錄等。

    每一個文件在此目錄樹中的文件名(包含完整路徑)都是獨一無二的。

2.文件的路徑表示

    絕對路徑爲:由根目錄(/)開始寫起的文件名或目錄名稱,例如/home/dmtsai/.bashrc。

    相對路徑爲相對於當前路徑的文件名寫法。

    .:表示當前目錄,也可以使用./來表示。

    ..:表示上一層目錄,也可以../來表示。

3.文件命名法則

    文件是磁盤上的一段存儲空間中存儲的數據,它通常基於文件名引用文件;故我們要做到按名存取,知名見義。

    嚴格區分字符大小寫;

    目錄是文件的路徑映射,從本質上來說也是文件,在同一個路徑下,兩個文件不能同名;

    支持使用除/以外的所有字符;但不建議使用特殊字符命名文件;

    最長不能超過255個字符。

4.文件系統結構詳解

/bin:所有用戶可用的基本命令程序文件;

/sbin:實現管理功能的程序文件;

/boot:引導加載器的靜態文件;內核、ramdisk(initrd, initramfs)文件亦在此處;能獨立分區

/dev:存儲特殊文件或設備文件;

/etc:系統和應用程序的配置文件;

/home:普通用戶的家目錄;能獨立分區。每個都有自己專用的家目錄;

/root:管理員的家目錄;

/lib:共享庫文件,以內核模塊文件;不能獨立分區

/lib64:64位系統特有的存放64位共享庫的路徑;不能獨立分區

/media:掛載便攜式設備;

/mnt:掛載臨時文件系統;

/opt:第三方應用程序的安裝路徑(Add-on software packages);

/srv:當前系統提供的服務運行中的用到的中間數據(Data for services provided by this system);

/tmp:臨時文件存儲位置,所有用戶均可使用;使用 ls -ld /tmp 命令查詢結果: 顯示爲 /tmp 爲綠色 且權限屬性最後一個爲t

/usr:/usr Hierarchy,全局共享只讀數據;(文件系統第二重要組成部分、第二分區)能獨立分區

bin, sbin:可執行程序;

lib, lib64 :庫文件;

include:C程序頭文件;

share:平臺的獨立的共享數據文件;

local:第三方應用程序安裝路徑;

src:程序源代碼;

/usr/local:第三方應用程序安裝路徑;可使用獨立分區;

/var:可變數據存儲位置;不能獨立分區

cache:應用程序緩存數據;

lib:可變狀態信息數據;

log:日誌文件目錄;

lock:鎖文件;

run:進程相關的數據,主要用戶存儲pid文件;

/proc:基於內存的虛擬文件系統; 用於爲內核及進程存儲其相關信息; 它們多數爲內核參數,例如net.ipv4.ip_forward,虛擬爲/proc/sys/net/ipv4/ip_forward;以後系統調優多數爲        調此目錄下的文件參數值

/sys:sysfs虛擬文件系統,是一種提供了比/proc更爲理想的訪問內核數據的另一個途徑;其主要作用在於爲管理Linux系統上的設備提供一種統一模型的接口;


二、常用命令的使用

1.顯示當前目錄:pwd

pwd:printing working directory

    echo  $PWD :顯示目錄

    echo  $OLDPWD :顯示父目錄

[root@node1 ~]#cd /tmp
[root@node1 /tmp]#pwd
/tmp
[root@node1 /tmp]#echo $PWD    
/tmp
[root@node1 /tmp]#echo $OLDPWD
/root

2.目錄切換:cd

cd:change directory

  用法:cd  [/PATH/TO/SOMEDIR]

cd:切換回家目錄;

      注意:bash中,~表示用戶的家目錄;

cd ~:切換回家目錄;

       cd ~USERNAME:切換至指定用戶的家目錄;只有管理員纔有的權限;

cd -:在上一次所在目錄與當前目錄之間來回切換;此命令比較有用。

[root@node1 ~]#cd /tmp
[root@node1 /tmp]#pwd
/tmp
[root@node1 /tmp]#cd -
/root

3.ls:list,列出指定目錄下的內容,默認爲當前目錄

ls  [OPTION]...  [FILE]...

        -a, --all:顯示所有文件,包括.和..在內所有隱藏文件; 

-A, --almost-all 列出目錄中除了 “當前目錄 .”和“父目錄 ..”之外的所有文件,包括隱藏文件

-l:use a long listing format(按長列表輸出格式顯示)

-F,--classify : append indicator (one of */=>@|) to entries 給條目追加文件類型和標識符,區分文件和目錄(*表示系統上可運行的文件)

-h, --human-readable:對數值做單位換算(K表示千字節,M表示兆字節,G表示吉字節);

-i: 顯示每個文件的索引值(inode)  

-d:查看目錄自身的屬性;  

-R:recursive,遞歸顯示;可顯示目錄及目錄裏面文件的內容

-r:reverse,降序顯示;

--color={never|auto|always}:何時着色顯示;

-s:輸出每個文件的塊大小;

-S: 按文件大小排序輸出;

[root@node1 ~]#ls  -l /root
total 4
-rw-r-xr-x  1 root root    0 Jul 30 10:50 1.sh
-rw-------. 1 root root 2639 Jul 12 07:59 anaconda-ks.cfg

 drwxr-xr-x:

 d:文件類型,一個字符;

 rwxr-xr-x:文件權限,permission;

         perm:

         r:readable

         w:writable

         x: excutable

         權限三位一組:

         左三位:屬主的訪問權限;

         中三位:屬組的所有用戶的訪問權限;

         右三位:其它(other)用戶的訪問權限;

1:數字,表示文件被硬鏈接的次數;

root:一個用戶名,表示當前文件的屬主(owner);

root:一個組名,表示當前文件屬組(group);

2639:一個數值,表示當前文件的size,默認單位爲字節;可以跟 -h 選項一起使用

Jul  12 08:59 :一個時間,表示文件最近一次被修改的時間;

anaconda-ks.cfg:文件名;


4.顯示文件或文件系統的狀態:stat

 stat - display file or file system status

語法格式:

stat [OPTION]... FILE...

文件的數據組成部分:

元數據(metadata):文件的元數據是指文件的屬性 比如大小、權限、屬主屬組、時間戳等等;存放於文件系統中的inode; 

數據(data):存放在數據塊(data blocks)上;

   注:任何一個磁盤格式化的時候都會把磁盤分爲數據區和元數據區;而stat命令主要用於查看inode的相關信息的;

文件的三個時間戳:

最近訪問時間(access time:atime),文件最近一次被訪問的時間

最近修改時間(modify time:mtime),文件最近一次被修改的時間(數據)

最近改動時間(change time:ctime),文件最近一次改動的時間(元數據)

[root@node1 ~]#stat 1.sh 
  File: ‘1.sh’
  Size: 0         Blocks: 0          IO Block: 4096   regular empty file
Device: 802h/2050dInode: 201368793   Links: 1
Access: (0655/-rw-r-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2016-07-30 10:50:18.860790111 +0800
Modify: 2016-07-30 10:50:18.860790111 +0800
Change: 2016-07-30 10:51:01.820972642 +0800
 Birth: -

5.touch命令

Update the access and modification times of each FILE to the current time

touch - change file timestamps

用法:

    touch [OPTION]... FILE...

-t STAMP:指定時間格式:[[CC]YY]MMDDhhmm[.ss](手動指定時間,如果不指都表示當下時間)

        如# touch -t 201606131434 b

-a:僅修改atime;

-m:僅修改mtime;

-c:不創建文件;

 注:如果touch一個不存在的文件,則會創建一個空文件;

    使用 # touch  $(date +%F-%H-%M-%S) 命令:可以創建一個以當下時間爲主的文件

[root@node1 ~]#touch `date +%F-%H-%M-%S`
[root@node1 ~]#ll
total 4
-rw-r-xr-x  1 root root    0 Jul 30 10:50 1.sh
-rw-r--r--  1 root root    0 Jul 30 11:03 2016-07-30-11-03-46
-rw-------. 1 root root 2639 Jul 12 07:59 anaconda-ks.cfg

6.cp命令:copy

cp - copy files and directories

單源複製: cp [OPTION]... [-T]  SOURCE  DEST

多源複製: cp [OPTION]... SOURCE...  DIRECTORY

   cp [OPTION]... -t DIRECTORY SOURCE...

        常用選項:

-i:交互式複製,即覆蓋目標文件之前提醒用戶確認;

-f:強制覆蓋目標文件;

-R, -r, --recursive:遞歸複製目錄及其內容;

-d:same as --no-dereference --preserve=links(保留鏈接本身的);

-P, --no-dereference:複製鏈接文件本身,而非默認的複製鏈接文件指向的源文件的內容(使用此選項複製鏈接類文件時相當於Windows上的快捷方式操作);

--preserve[=ATTR_LIST]:

指明保留的源文件屬性列表:

默認爲mode,ownership,timestamps;

額外:context(安全上下文), links(鏈接), xattr(擴展屬性), all

-a, --archive:歸檔複製(創建備份的)

-dR --preserve=all

注意:僅管理員可保留屬主和屬組屬性;

注:若-i和-f兩個選項同時使用時,會提供交互式操作給用戶提示

單源複製:cp [OPTION]... [-T]  SOURCE  DEST

如果DEST不存在(僅指基名所指定的文件不存在,路勁本身必須存在):則複製時先創建DEST文件,而後複製源文件的內容導入至目標文件;

如果DEST事先存在:

                        如果DEST是非目錄文件:則覆蓋目標文件;此操作極其危險,考慮到此centos定義 “cp=cp -i” 命令選項,提供交互式命令在複製時會有所提示;使用 \cp 可                          以使用命令本身,不使用命令別名);

如果DEST目錄:則在此目錄中創建一個與原文件同名的文件,則導入其內容;

[root@node1 ~]#alias |grep cp
alias cp='cp -i'
[root@node1 ~]#mkdir testdir
[root@node1 ~]#cp 1.sh  testdir/
[root@node1 ~]#cp 1.sh  testdir/
cp: overwrite ‘testdir/1.sh’? y
[root@node1 ~]#\cp  1.sh  testdir/

多源複製:

 基本前提:僅允許一種情形 DEST存在,且必須是目錄;否則即爲錯誤; 

[root@node1 ~]#cp 1.sh anaconda-ks.cfg  testdir/
cp: overwrite ‘testdir/1.sh’? y
[root@node1 ~]#ls testdir/
1.sh  anaconda-ks.cfg
[root@node1 ~]#cp 1.sh anaconda-ks.cfg  nodir
cp: target ‘nodir’ is not a directory

7.mv命令

Rename SOURCE to DEST, or move SOURCE(s) to DIRECTORY. Mandatory arguments to long options are mandatory for short options too.

    mv - move (rename) files

    mv [OPTION]... [-T] SOURCE DEST

    mv [OPTION]... SOURCE... DIRECTORY

    mv [OPTION]...  -t DIRECTORY  SOURCE...

    常用選項:

     -i, --interactive:使用交互式選項操作

     -f, --force  do not prompt before overwriting

         注意:源文件目錄與目標文件目錄相同時,爲rename機制;否則即爲move。 

      無論移動的源文件是文件還是目錄都不需要使用-R選項

8.rm命令

rm - remove files or directories

rm [OPTION]... FILE...

常用選項:

-i, --interactive

-f, --force

-r, -R, --recursive:遞歸刪除目錄及其內容(和cp命令一樣,刪除目錄時需要使用此選項);

    注意:Linux沒有回收站功能,所以不要隨意執行 “rm -rf  /”或“rm -rf  /*” 命令!


三、bash的特性之glob

glob:文件名通配;快速引用多個文件;文件名整體匹配度檢測;

元字符:基於元字符可編寫匹配模式(pattern);

*:匹配任意長度的任意字符;

?:匹配任意單個字符;

[ ]:匹配指定集合內的任意單個字符;

[a-z], [A-Z]:不區分字符大小寫;

[0-9] :0-9之間的任意單個數字

[a-z0-9]:既有字母又有數字的集合

 字符集合表示:

[[:upper:]]:所有大寫字母;

[[:lower:]]:所有小寫字母;

[[:digit:]]:所有的數字;

[[:alpha:]]:所有字母;

[[:alnum:]]:所有字母和數字;

[[:space:]]:空白字符;

[[:punct:]]:標點符號(punctuation);

[^ ]:匹配指定集合外的任意單個字符;

[^[:alpha:]]:所有的非字母集合

三、軟連接和硬鏈接

1.Linux鏈接概念

Linux鏈接分兩種,一種被稱爲硬鏈接(Hard Link),另一種被稱爲符號鏈接(Symbolic Link)。默認情況下,ln命令產生硬鏈接。

2.硬連接

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

3.軟連接

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

4.通過實驗加深理解

[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 4
201364821 -rw-------. 1 root root 2639 Jul 12 07:59 anaconda-ks.cfg
201368793 -rw-r--r--  2 root root    0 Jul 30 11:31 f1
201368793 -rw-r--r--  2 root root    0 Jul 30 11:31 f2
201364836 lrwxrwxrwx  1 root root    2 Jul 30 11:32 f3 -> f1

  從上面的結果中可以看出,硬連接文件f2與原文件f1的inode節點相同,均爲201368793,然而符號連接文件的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文件無效

5.總結

依此您可以做一些相關的測試,可以得到以下全部結論:

    1).刪除符號連接f3,對f1,f2無影響;

    2).刪除硬連接f2,對f1,f3也無影響;

    3).刪除原文件f1,對硬連接f2沒有影響,導致符號連接f3失效;

    4).同時刪除原文件f1,硬連接f2,整個文件會真正的被刪除。



   


    

    

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