文件系統是學習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,整個文件會真正的被刪除。