1. 程式人生 > 實用技巧 >跟光磊學Linux運維-深入淺出Linux檔案系統

跟光磊學Linux運維-深入淺出Linux檔案系統

跟光磊學Linux運維-深入淺出Linux檔案系統

跟光磊學Linux運維

Linux目錄結構介紹

和Windows以碟符(例如C盤、D盤)作為根目錄不同的是,Linux的檔案系統只有一個根目錄,使用/表示。

  • Linux系統中的目錄和檔案被組織成一個單根倒置樹結構

  • 以.開頭的檔案表示隱藏檔案

  • 路徑使用/(左斜線)分隔

  • 檔名區分大小寫(是否大小寫敏感和作業系統無關,而是和作業系統的檔案系統有關) ,例如/opt和/OPT是不同的概念

  • 檔名最長為255個位元組,包括路徑在內檔名最長為4095個位元組。

  • 不同型別的檔案,使用不同的顏色區分(檔名字尾不同,顏色不同),其中藍色表示目錄即資料夾,綠色表示可執行檔案,紅色表示壓縮檔案,淺藍色表示連結檔案(類似於windows的快捷方式),灰色表示其他檔案。檔案顏色的配置位於/etc/DIR_COLORS檔案中,如果想要定義其他檔案的顏色,直接修改該檔案即可。但是通常一般不建議修改預設檔案對應的顏色。

  • Linux系統的檔案命名除了斜槓和NUL,所有的字元都有效,但特殊字元的目錄名和檔案不推薦使用,有些字元需要使用引用來引用。

  • 每個檔案都有兩類資料:元資料(meta data)和資料(data),其中資料表示檔案的內容,而元資料表示檔案的屬性,例如檔案的大小,許可權,連結數,所有者等等都是檔案的元資料。

使用ls / 命令檢視根目錄結構

[root@centos8 ~]# ls /
bin  boot  data  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

使用tree命令檢視根目錄下的一級子目錄

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

Linux目錄結構規範(FHS)

不同的Linux發行版的系統目錄結構都是大同小異,Linux系統的目錄遵守LSB(Linux Standard Base)標準

檔案系統層次標準提供了文件介紹了目錄以及基本工具的詳細說明,在後期使用Linux按照目錄標準存放檔案。

Linux老司機如果想要了解Linux檔案系統目錄結構的功能,可以讀該文件。

FHS文件地址: https://www.pathname.com/fhs/pub/fhs-2.3.pdf

  • /boot 用於系統啟動引導檔案存放目錄,核心檔案(vmlinuxz)以及引導載入器(bootloader)都存放在此目錄下
  • /bin 存放所有使用者使用的基本命令,該目錄不能獨立分割槽,作業系統在啟動時會使用到該目錄下的檔案
  • /sbin 存放管理類的基本命令,該目錄不能獨立分割槽,作業系統在啟動時會使用到該目錄下的檔案
  • /lib 存放系統啟動時程式依賴的基本共享庫檔案以及核心模組檔案(/lib/modules);還有個目錄叫/lib64是專用於x86_64系統上輔助共享庫檔案的位置
  • /etc 存放系統的配置檔案
  • /home 普通使用者的家目錄
  • /root 管理員的家目錄
  • /media 行動式移動裝置的掛載點
  • /mnt 臨時檔案系統掛載點
  • /dev 用於存放裝置檔案(例如磁碟)以及特殊檔案儲存位置
  • /opt 用於存放第三方應用程式的安裝位置,例如Gitlab等等
  • /srv 系統上執行的服務所需要用到的資料
  • /tmp 臨時檔案儲存位置
  • /var 存放臨時變化的資料,例如日誌
  • /usr 存放應用程式和檔案,系統安裝時的軟體包預設的安裝路徑,等同於Windows系統的Windows和Program Files目錄
  • /misc 雜項,使用autfofs可以實現自動掛載光碟目錄
  • /sys 輸出當前系統上硬體裝置相關資訊虛擬檔案系統

/proc和/sys目錄比較特殊,一般的目錄都可以使用du -sh檢視大小,而/sys和/proc是虛擬的目錄,載入在記憶體中,無法檢視大小

[root@centos8 ~]# du -sh /sys #/sys目錄大小為0,因為是載入在記憶體中
0	/sys
[root@centos8 ~]# cat /proc/partitions  #檢視/proc目錄的磁碟分割槽檔案partitions
major minor  #blocks  name

   8        0  209715200 sda
   8        1    2097152 sda1
   8        2  104857600 sda2
   8        3   52428800 sda3
   8        4          1 sda4
   8        5    4194304 sda5
  11        0    8038400 sr0

使用tree命令檢視/usr下的一級目錄

[root@centos8 ~]# tree -L 1 /usr #檢視/usr目錄下的一級子目錄
/usr
├── bin
├── games
├── include
├── lib
├── lib64
├── libexec
├── local
├── sbin
├── share
├── src
└── tmp -> ../var/tmp

使用lsblk檢視光碟和掛載點資訊

[root@centos8 ~]# lsblk #檢視光碟和掛載點資訊
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0  200G  0 disk 
├─sda1   8:1    0    2G  0 part /boot
├─sda2   8:2    0  100G  0 part /
├─sda3   8:3    0   50G  0 part /data
├─sda4   8:4    0    1K  0 part 
└─sda5   8:5    0    4G  0 part [SWAP]
sr0     11:0    1  7.7G  0 rom  /run/media/guanglei/CentOS-8-2-2004-x86_64-dvd

/misc 目錄掛載光碟前首先需要安裝並啟用autofs,系統預設沒有安裝autofs

[root@centos7 ~]# systemctl status autofs # 檢視autofs是否已經安裝
Unit autofs.service could not be found.

安裝並啟用autofs,啟動後可以使用systemctl status autofs命令來檢視autofs的狀態,如果狀態是Active

[root@centos7 ~]# yum install -y autofs # 安裝autofs
[root@centos7 ~]# systemctl start autofs # 啟動autofs
[root@centos7 ~]# systemctl status autofs # 檢視autofs
● autofs.service - Automounts filesystems on demand
   Loaded: loaded (/usr/lib/systemd/system/autofs.service; disabled; vendor preset: disabled)
   Active: active (running) since Fri 2020-08-28 21:27:48 CST; 2s ago
 Main PID: 3083 (automount)
    Tasks: 5
   CGroup: /system.slice/autofs.service
           └─3083 /usr/sbin/automount --systemd-service --dont-check-daemon

Aug 28 21:27:47 centos7.ittimeline.net systemd[1]: Starting Automounts filesystems on demand...
Aug 28 21:27:48 centos7.ittimeline.net systemd[1]: Started Automounts filesystems on demand.

autofs啟動之後檢視根目錄會發現多了一個misc目錄

[root@centos7 ~]# ls / #檢視根目錄檔案列表
bin   data  etc   lib    media  mnt  opt   root  sbin  sys  usr
boot  dev   home  lib64  misc   net  proc  run   srv   tmp  var

如果系統掛載了光碟,勾選啟動時連線

則可以在autofs服務啟動後進入/misc/cd目錄下訪問光碟的檔案

[root@centos7 ~]# cd /misc/cd #切換到/misc/cd目錄
[root@centos7 cd]# ls
CentOS_BuildTag  EULA  images    LiveOS    repodata              RPM-GPG-KEY-CentOS-Testing-7
EFI              GPL   isolinux  Packages  RPM-GPG-KEY-CentOS-7  TRANS.TBL

也可以檢視磁碟資訊

[root@centos7 cd]# lsblk # 檢視磁碟分割槽
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0  200G  0 disk 
├─sda1   8:1    0    2G  0 part /boot
├─sda2   8:2    0  100G  0 part /
├─sda3   8:3    0   50G  0 part /data
├─sda4   8:4    0    1K  0 part 
└─sda5   8:5    0    8G  0 part [SWAP]
sr0     11:0    1  9.6G  0 rom  /misc/cd

不過如果系統重啟後是無法訪問/misc目錄,要解決該問題,systemctl enable autofs命令可以將autofs設為開機啟動

[root@centos7 cd]# systemctl enable autofs #設定autofs為開機啟動
Created symlink from /etc/systemd/system/multi-user.target.wants/autofs.service to /usr/lib/systemd/system/autofs.service.

也可以使用systemctl enable --now autofs命令同時啟動autofs並且設定為開機啟動

[root@centos8 cd]# systemctl enable --now autofs #啟用autofs
Created symlink /etc/systemd/system/multi-user.target.wants/autofs.service → /usr/lib/systemd/system/autofs.service.

CentOS7 目錄變化

自CentOS7以後把一些作用相同的目錄合併

  • /bin和/usr/bin
  • /lib和/usr/lib
  • /lib64和/usr/lib64
  • /sbin和/usr/sbin

其中/bin、/lib、/lib64、/sbin是連結檔案。

[root@centos8 ~]# ls -ld /bin /usr/bin /lib /usr/lib /lib64 /usr/lib64 /sbin /usr/sbin
lrwxrwxrwx.   1 root root     7 May 11  2019 /bin -> usr/bin
lrwxrwxrwx.   1 root root     7 May 11  2019 /lib -> usr/lib
lrwxrwxrwx.   1 root root     9 May 11  2019 /lib64 -> usr/lib64
lrwxrwxrwx.   1 root root     8 May 11  2019 /sbin -> usr/sbin
dr-xr-xr-x.   2 root root 40960 Aug 24 08:05 /usr/bin
dr-xr-xr-x.  37 root root  4096 Aug 24 08:04 /usr/lib
dr-xr-xr-x. 117 root root 69632 Aug 24 08:07 /usr/lib64
dr-xr-xr-x.   2 root root 20480 Aug 24 08:05 /usr/sbin

Linux的檔案型別

使用ll(等價於ls -l)命令可以檢視指定目錄下的檔案型別,ll輸出的第一個字元表示檔案型別

  • - 表示普通檔案
  • d表示目錄(directory)檔案
  • b表示塊(block)裝置檔案,以塊(4k位元組)的方式來讀寫檔案
  • c表示字元(character)裝置檔案,表示邏輯裝置檔案
  • l表示符號(link)連結檔案
  • p表示管道(pipe)檔案,基於單向傳輸實現程式的通訊(單工,收音機就是單工)
  • s表示套接字(socket)檔案,實現應用程式的雙向通訊 (雙工,對講機就是半雙工,手機就是全雙工)

除了普通檔案,在運維時操作其他檔案需要謹慎
使用ll命令檢視檔案資訊時,輸出的第一個字母就是檔案型別

檢視普通檔案

ll檢視檔案詳細資訊,輸出結果的第一個字母-表示該檔案是普通檔案

[root@centos8 ~]# ll
total 8
-rw-------. 1 root root 1591 Aug 24 08:08 anaconda-ks.cfg
-rw-r--r--. 1 root root 1701 Aug 24 22:36 initial-setup-ks.cfg

檢視目錄檔案

ll檢視檔案詳細資訊,輸出結果的第一個字母d表示該檔案是目錄檔案

[root@centos8 ~]# ls -l -d /data
drwxr-xr-x. 2 root root 6 Aug 24 07:58 /data

檢視字元檔案

ll檢視字元裝置詳細資訊,輸出結果的第一個字母c表示該檔案是字元檔案
字元裝置的讀寫是順序的,例如鍵盤就是一個字元裝置,字元裝置讀寫沒有快取

[root@centos8 ~]# ll /dev/zero 
crw-rw-rw-. 1 root root 1, 5 Aug 28 21:01 /dev/zero

檢視塊裝置檔案

ll檢視塊裝置-磁碟的詳細資訊,輸出結果的第一個字母b表示該檔案是塊裝置檔案
塊裝置讀寫是隨機,塊裝置讀寫有快取

guanglei@ubuntu-server:~$ ll /dev/sda #檢視Ubuntu-Server的磁碟
brw-rw---- 1 root disk 8, 0 Aug 29 00:33 /dev/sda

將塊裝置/dev/zero寫入/root/block.txt檔案中,數量是1,塊裝置檔案大小是1

[root@centos8 ~]# dd if=/dev/zero of=block.txt bs=1 count=1 #將塊裝置/dev/zero寫入/root/block.txt檔案中,數量是1,塊裝置大小是1
1+0 records in
1+0 records out
1 byte copied, 5.8654e-05 s, 17.0 kB/s
[root@centos8 ~]# ll block.txt # 
-rw-r--r--. 1 root root 1 Oct  6 10:18 block.txt
[root@centos8 ~]# hexdump block.txt #檢視寫入檔案的十六進位制的資料 0000是十六進位制0的表示方式
0000000 0000
0000001

檢視socket套接字檔案

ll檢視rpcbind.sock 檔案詳細資訊,輸出結果的第一個字母s表示該檔案是套接字檔案

[root@centos7 ~]# ll /run/rpcbind.sock 
srw-rw-rw-. 1 root root 0 Aug 29 08:33 /run/rpcbind.sock

檔案路徑

Linux檔案系統中包含路徑在內的檔名稱最長4095個位元組。

dirname獲取檔案的目錄名稱
basename獲取完整路徑的檔名稱,不要上級目錄

[root@centos8 data]# basename /etc/sysconfig/network
network
[root@centos8 data]# dirname /etc/sysconfig/network
/etc/sysconfig

建立一個檔案,檔案目錄由dirname /etc/sysconfig/network執行的結果決定

[root@centos8 data]# touch `dirname /etc/sysconfig/network`/test.txt 
[root@centos8 sysconfig]# dirname /etc/sysconfig/network #檢視/etc/sysconfig/network的dirname
/etc/sysconfig
[root@centos8 sysconfig]# cd /etc/sysconfig/ #切換到 /etc/sysconfig/ 目錄
[root@centos8 sysconfig]# ll test.txt # 檢視test.txt檔案的屬性資訊
-rw-r--r--. 1 root root 0 Oct  6 11:02 test.txt

在訪問檔案系統時,會涉及到兩種路徑:絕對路徑和相對路徑,其中絕對路徑是從根目錄開始的路徑相對路徑是相對於當前路徑,特殊場景下是相對於某個目錄的位置

[root@centos8 ~]# cd /etc/sysconfig
[root@centos8 sysconfig]# pwd

[root@centos8 sysconfig]# ll /etc/issue
-rw-r--r--. 1 root root 23 Jun  3 09:02 /etc/issue
[root@centos8 sysconfig]# ll ../issue
-rw-r--r--. 1 root root 23 Jun  3 09:02 ../issue
[root@centos8 sysconfig]# ll ./network
-rw-r--r--. 1 root root 22 Jul 26 12:56 ./network

..表示上級目錄,.表示當前目錄

使用絕對路徑訪問linux核心

[root@centos8 sysconfig]# ll /boot/vmlinuz-4.18.0-193.el8.x86_64   #使用絕對路徑訪問linux核心
-rwxr-xr-x. 1 root root 8913656 May  8 19:07 /boot/vmlinuz-4.18.0-193.el8.x86_64

使用相對路徑訪問Linux核心

對比絕對路徑而言,絕對路徑更加簡潔

[root@centos8 sysconfig]# ll ../../boot/vmlinuz-4.18.0-193.el8.x86_64 
-rwxr-xr-x. 1 root root 8913656 May  8 19:07 ../../boot/vmlinuz-4.18.0-193.el8.x86_64

使用絕對路徑或者相對路徑建立特殊檔案

[root@centos8 sysconfig]# touch /data/-
[root@centos8 sysconfig]# ll /data/
total 0
-rw-r--r--. 1 root root 0 Aug  1 17:47 -
-rw-r--r--. 1 root root 0 Aug  1 17:21 TEST.txt
[root@centos8 sysconfig]# cd /data/
[root@centos8 data]# touch ./-h
[root@centos8 data]# ll
total 0
-rw-r--r--. 1 root root 0 Aug  1 17:47 -
-rw-r--r--. 1 root root 0 Aug  1 17:47 -h
-rw-r--r--. 1 root root 0 Aug  1 17:21 TEST.txt

使用相對路徑刪除特殊檔案

[root@centos8 data]# rm ./-
rm: remove regular empty file './-'? y
[root@centos8 data]# rm ./-h
rm: remove regular empty file './-h'? y
[root@centos8 data]# ll
total 0
-rw-r--r--. 1 root root 0 Aug  1 17:21 TEST.txt

windows和linux文字格式差異以及編碼轉換

在windows中使用記事本建立的普通文字檔案,檔案的內容是每行一個字元

然後在xshell中使用yum install -y lrzsz安裝檔案上傳元件,然後使用rz命令上傳windows.txt

[root@centos7 data]# yum install -y lrzsz
[root@centos7 data]# rz

上傳以後在Linux中使用file檢視windows.txt檔案型別,其輸出結果是 ASCII text, with CRLF line terminators

[root@centos7 data]# file windows.txt 
windows.txt: ASCII text, with CRLF line terminators

然後使用touch linux.txt 建立文字檔案linux.txt,並使用nano編輯器編輯和windows.txt檔案一樣的內容

[root@centos7 data]# nano linux.txt
[root@centos7 data]# cat linux.txt 
a
b
c
[root@centos7 data]# cat windows.txt 
a
b
c

使用ll 命令檢視windows.txt和linux.txt的檔案大小,發現即使文字內容一樣,但是大小不一樣

[root@centos7 data]# ll windows.txt  linux.txt 
-rw-r--r--. 1 root root 6 Aug 29 13:10 linux.txt
-rw-r--r--. 1 root root 9 Aug 29 13:08 windows.txt

然後使用hexdump命令檢視兩個文字檔案的十六進位制儲存,經過對比發現是回車換行的差異。

[root@centos7 data]# hexdump -C windows.txt 
00000000  61 0d 0a 62 0d 0a 63 0d  0a                       |a..b..c..|
00000009
[root@centos7 data]# hexdump -C linux.txt 
00000000  61 0a 62 0a 63 0a                                 |a.b.c.|
00000006

Unix/Linux為了解決記憶體0a代表回車換行,而windows使用0a表示換行,0d表示回車。

為了解決該差異性,可以使用dos2unix來將windows.txt轉換為linux.txt一樣的文字格式,dos2unix預設沒有安裝,首次執行會提示 dos2unix: command not found...

[root@centos7 data]# dos2unix windows.txt 
bash: dos2unix: command not found...

使用yum install -y dos2unix 命令安裝即可

[root@centos7 data]# yum install -y dos2unix

安裝完成後使用dos2unix windows.txt命令將其轉換為linux系統的文字檔案格式

[root@centos7 data]# dos2unix windows.txt 
dos2unix: converting file windows.txt to Unix format ...
[root@centos7 data]# file windows.txt 
windows.txt: ASCII text

轉換完成後windows.txt和linux.txt的檔案大小一致

[root@centos7 data]# ll windows.txt  linux.txt 
-rw-r--r--. 1 root root 6 Aug 29 13:10 linux.txt
-rw-r--r--. 1 root root 6 Aug 29 13:23 windows.txt

windows.txt和linux.txt的底層儲存的內容也是一致

[root@centos7 data]# hexdump  -C windows.txt 
00000000  61 0a 62 0a 63 0a                                 |a.b.c.|
00000006
[root@centos7 data]# hexdump -C linux.txt 
00000000  61 0a 62 0a 63 0a                                 |a.b.c.|
00000006

linux.txt轉換windows的格式,使用unix2dos轉換即可。

那麼亂碼是如何產生的呢?

首先在windows系統中建立一個檔案,檔案內容為高階Linux運維工程師養成記


content.txt
儲存檔案的編碼是ANSI,windows10預設的編碼已經是UTF-8,因此這裡設成ANSI

然後使用rz命令上傳到/data目錄下,使用cat命令檢視檔案內容,結果是亂碼

[root@centos7 data]# cat content.txt 
???Linux???¤??????[root@centos7 data]# 

使用hexdump檢視檔案的十六進位制表示,發現漢字是佔用兩個位元組,而UTF-8中漢字佔據3個位元組,因此解碼失敗。
如果建立檔案的編碼和檢視檔案的編碼不一致,則會造成亂碼。

[root@centos7 data]# hexdump -C content.txt 
00000000  b8 df bc b6 4c 69 6e 75  78 d4 cb ce ac b9 a4 b3  |....Linux.......|
00000010  cc ca a6 d1 f8 b3 c9 bc  c7                       |.........|
00000019

因此需要將content.txt的編碼改成UTF-8,這裡為了區分,將UT-8編碼的content.txt檔案重新命名為content-utf8.txt

然後使用cat命令檢視content-utf8檔案,沒有亂碼

[root@centos7 data]# cat content-utf8.txt 
高階Linux運維工程師養成記[root@centos7 data]# 

不同的編碼(ASNI和UTF-8)儲存相同的檔案,其佔據的記憶體大小是不一樣的。
UTF-8雖然支援全世界的文字,但是佔用記憶體比ASNI大。

[root@centos7 data]# ll content.txt  content-utf8.txt 
-rw-r--r--. 1 root root 25 Aug 29 13:38 content.txt
-rw-r--r--. 1 root root 35 Aug 29 13:44 content-utf8.txt

iconv命令可以將ASNI編碼轉換為UTF-8編碼

[root@centos7 data]# iconv -f gb2312 content.txt  -o content-UTF8.txt
[root@centos7 data]# file content-UTF8.txt 
content-UTF8.txt: UTF-8 Unicode text, with no line terminators

轉換後檢視檔案內容也不是亂碼

[root@centos7 data]# cat content-UTF8.txt 
高階Linux運維工程師養成記[root@centos7 data]# 

再次將content-UTF8.txt 轉換為ANSI編碼

[root@centos7 data]# iconv -f utf-8 -t gb2312 content-UTF8.txt  -o windows-code 
[root@centos7 data]# file windows-code 
windows-code: ISO-8859 text, with no line terminators

檔案元資料和節點表結構

inode表結構

之前在安裝作業系統時,將一塊硬碟分成了四個分割槽,每個分割槽有自己的編號(sda1,sda2,sda3,sda4,sda5)和目錄結構

[root@centos7 data]# lsblk
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0  200G  0 disk 
├─sda1   8:1    0    2G  0 part /boot
├─sda2   8:2    0  100G  0 part /
├─sda3   8:3    0   50G  0 part /data
├─sda4   8:4    0    1K  0 part 
└─sda5   8:5    0    8G  0 part [SWAP]
sr0     11:0    1  9.6G  0 rom  

而每個分割槽目錄下儲存的檔案資料分為元資料和資料本身兩部分組成,其中元資料用於表示檔案的屬性,比如檔案的時間(Timestamps)、大小(Size)、所屬組(Group info)以及所主(Owner info)和許可權(Mode)等等。檔案的元資料儲存在node表中,node表中有很多條記錄組成,每條記錄對應一個檔案的元資料資訊

  • inode number 節點號
  • 檔案型別
  • 許可權
  • UID
  • GID
  • 連結數(指向檔名路徑名稱的個數)
  • 檔案的大小和不同的時間戳
  • 指向磁碟上檔案的資料塊指標
  • 有關檔案的其他資料

檔案節點表儲存檔案的內部結構

指標按照不同的檔案大小分為直接指標、間接指標和雙重間接指標。

直接指標有12個,直接塊指標指向資料塊,每個資料塊是4k大小,因此如果檔案的大小不超過48k,使用直接指標指向資料塊即可。
如果檔案大小超過了48k,並且小於4M,那麼就需要使用間接指標,間接指標指向的是指標塊,指標塊本身不存放資料,大小也是4K,存放的是指標,每個指標佔用4個位元組的空間,合計就是1024個指標,最多指向1024*4k即4M大小的檔案。
如果檔案大小超過4M,不超過4G,那麼就需要使用雙重間接塊指標,雙重間接塊指標指向的是一個檔案塊指標,依此類推。

檔案節點表儲存目錄的內部結構

和檔案不同的是,資料夾儲存的資料就是該目錄的檔案列表以及inode number的對應關係。
檔名放在目錄中,而不是放在節點表中。

資料存在磁碟上時,每個檔案都有唯一的索引節點編號,建立檔案之後,在檢視檔案詳細資訊時,可以使用ls -i選項檢視,節點編號由系統自動分配。

[root@centos7 data]# ls -i
76 file10.log  68 file2.log  70 file4.log  72 file6.log  74 file8.log
67 file1.log   69 file3.log  71 file5.log  73 file7.log  75 file9.log

每個分割槽的節點編號也是有限制的,例如/boot分割槽的可用節點是1048236

使用df -i 加分割槽路徑 可以檢視分割槽的最大inode數

[root@centos7 data]# df -i /boot
Filesystem      Inodes IUsed   IFree IUse% Mounted on
/dev/sda1      1048576   340 1048236    1% /boot

每建立一個檔案,可用的檔案編號就會自動減少

inode從之前的1048236變成了1048235

[root@centos7 data]# cd /boot
[root@centos7 boot]# touch test.txt
[root@centos7 boot]# df -i /boot
Filesystem      Inodes IUsed   IFree IUse% Mounted on
/dev/sda1      1048576   341 1048235    1% /boot

如果磁碟的節點編號耗盡,那麼即使磁碟空間沒有滿,也無法再使用。

[root@centos7 boot]# mkdir testdir
[root@centos7 boot]# cd testdir/

[root@centos7 testdir]# df -i /boot
Filesystem      Inodes IUsed   IFree IUse% Mounted on
/dev/sda1      1048576   342 1048234    1% /boot

[root@centos8 testdir]# echo file{1..130761}|xargs touch
touch: cannot touch 'file1048235': No space left on device

本質原因是檔案節點編號耗盡

[root@centos7 testdir]# df -i /boot
Filesystem      Inodes   IUsed IFree IUse% Mounted on
/dev/sda1      1048576 1048576     0  100% /boot

刪除檔案後便可以再次在/boot目錄下建立檔案

[root@centos7 testdir]# rm -rf /boot/testdir
[root@centos7 boot]# df -i /boot
Filesystem      Inodes IUsed   IFree IUse% Mounted on
/dev/sda1      1048576   341 1048235    1% /boot

cp命令和inode

在執行cp命令時,系統會分配一個空閒的inode,並在inode表彙總生成新條目,在目錄中建立一個目錄項,將名稱與inode編號關聯,並拷貝資料生成新的檔案。

rm和inode

在執行rm命令時,連結數遞減,從而釋放的inode號可以被重複使用,把資料塊放在空閒列表中,刪除目錄項,資料實際上不會立馬被刪除,但是當另一個檔案使用資料塊時會被覆蓋。

在建立檔案時,預設的連結數為1

數字1表示硬連結數為1

[root@centos8 data]# ll -i /data
total 0
140 -rw-r--r--. 1 root root 0 Aug  9 12:40 file10.log
131 -rw-r--r--. 1 root root 0 Aug  9 12:40 file1.log
132 -rw-r--r--. 1 root root 0 Aug  9 12:40 file2.log
133 -rw-r--r--. 1 root root 0 Aug  9 12:40 file3.log
134 -rw-r--r--. 1 root root 0 Aug  9 12:40 file4.log
135 -rw-r--r--. 1 root root 0 Aug  9 12:40 file5.log
136 -rw-r--r--. 1 root root 0 Aug  9 12:40 file6.log
137 -rw-r--r--. 1 root root 0 Aug  9 12:40 file7.log
138 -rw-r--r--. 1 root root 0 Aug  9 12:40 file8.log
139 -rw-r--r--. 1 root root 0 Aug  9 12:40 file9.log

當在同一個分割槽下建立一個硬連結後連結數會增加

file1.log和file1.log.link的連結數都是2,硬連結的本質是同一個檔案有多個檔名

[root@centos8 data]# ln file1.log  file1.log.link
[root@centos8 data]# ll !*
ll file1.log file1.log.link
-rw-r--r--. 2 root root 0 Aug  9 12:40 file1.log
-rw-r--r--. 2 root root 0 Aug  9 12:40 file1.log.link

當刪除file1.log時,硬連結檔案不會受影響,但是連結數會遞減

[root@centos8 data]# rm file1.log
[root@centos8 data]# ll|grep file1.log.link 
-rw-r--r--. 1 root root 0 Aug  9 12:40 file1.log.link

資料夾不能建立硬連結

mv和inode

如果mv命令的目標和源在相同的檔案系統分割槽時,用新的檔名建立新的目錄項,刪除就目錄條目對應舊的檔名,不影響inode表(除了時間戳)或磁碟上的資料位置:沒有資料被移動。

[root@centos7 data]# touch test.txt
[root@centos7 data]# ls -i test.txt 
67 test.txt
[root@centos7 data]# mkdir -p  parent/child
[root@centos7 data]# mv test.txt  parent/child/
[root@centos7 data]# ls -i parent/child/test.txt 
67 parent/child/test.txt

如果mv命令的目標和源在不同的檔案系統分割槽時,mv相當於cp和rm

[root@centos7 data]# ls -i parent/child/test.txt 
67 parent/child/test.txt
[root@centos7 data]# mv /data/parent/child/test.txt  /boot
mv: overwrite ‘/boot/test.txt’? y
[root@centos7 data]# ls -i /boot/test.txt 
113 /boot/test.txt

軟連結和硬連結

檔案連結型別-硬連結

硬連結實現一個檔案可以有多個檔名

檔案連結型別分為硬連結和軟連結,硬連結在使用過程中有些限制,只能在同一個分割槽的不同目錄下針對檔案建立硬連結。
以/etc目錄下的fstab檔案在/data/d1/d2/d3目錄下建立一個硬連結,然後檢視兩個檔案的詳細資訊,發現檔案完全一致。

ln即link的縮寫,用於建立連結,預設是建立硬連結。

建立硬連結時,目錄必須存在

[root@centos7 data]# cp /etc/fstab  f1
[root@centos7 data]# mkdir -p d1/d2/d3
[root@centos7 data]# ln f1 d1/d2/d3/f1
[root@centos7 data]# ll !*
ll f1 d1/d2/d3/f1
-rw-r--r--. 2 root root 595 Aug 30 17:57 d1/d2/d3/f1
-rw-r--r--. 2 root root 595 Aug 30 17:57 f1

既然硬連結是一個檔案有多個檔名,那麼現在修改f1的內容

然後再檢視/data/f1和/data/d1/d2/d3/f1的檔案大小,發現大小一致

[root@centos7 data]# ll f1 d1/d2/d3/f1 
-rw-r--r--. 2 root root 617 Aug 30 18:00 d1/d2/d3/f1
-rw-r--r--. 2 root root 617 Aug 30 18:00 f1

如果刪除f1,那麼連結檔案/data/d1/d2/d3/f1依然能夠訪問,只是連結數減少了一個。

[root@centos7 data]# rm f1
rm: remove regular file ‘f1’? y
[root@centos7 data]# cat d1/d2/d3/f1 

#
# /etc/fstab
# Created by anaconda on Tue Aug 25 14:08:19 2020
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
# this si modify conent
UUID=15c0ca95-1555-428d-a209-4af18a8e7dce /                       xfs     defaults        0 0
UUID=4623526f-cc6c-4bb9-bd20-728b2808d737 /boot                   xfs     defaults        0 0
UUID=ee8afba5-4d9b-4133-8861-863aa03e0d2d /data                   xfs     defaults        0 0
UUID=4e13f43c-57ae-4fa2-9640-54f4b92fb920 swap                    swap    defaults        0 0

[root@centos7 data]# ll d1/d2/d3/f1 
-rw-r--r--. 1 root root 617 Aug 30 18:00 d1/d2/d3/f1

每次建立連結,對應的連結數也會增加,同樣每次刪除檔案時連結數會減少

[root@centos7 data]# mkdir -p file1/fiel2/file3
[root@centos7 data]# cp /etc/fstab f1
[root@centos7 data]# ln f1 file1/fiel2/file3/f1
[root@centos7 data]# ll !*
ll f1 file1/fiel2/file3/f1
-rw-r--r--. 2 root root 595 Aug 30 18:07 f1
-rw-r--r--. 2 root root 595 Aug 30 18:07 file1/fiel2/file3/f1

/boot和/opt處於不同的分割槽,分別是boot分割槽和根分割槽,硬連結不能跨分割槽建立

因為硬連結的本質是給同一個檔案取多個名字

[root@centos7 data]# ln f1 /opt/f1
ln: failed to create hard link ‘/opt/f1’ => ‘f1’: Invalid cross-device link

資料夾不能建立硬連結,因為可能發生資料夾巢狀

[root@centos7 data]# ln file1  file1/fiel2/file3/
ln: ‘file1’: hard link not allowed for directory

檔案連結型別-軟連結

ln命令預設建立的連結是硬連結,而ln -s建立的連結就是軟連結,類似於windows中的快捷方式。

將/etc目錄下的fstab檔案複製到/data目錄下並重命名f1,並建立軟連結f1.link,對比之後發現軟連結的f1.link檔案大小和原始檔f1不一樣,
而且建立軟連結時原始檔f1的連結數也沒有增加,軟連結和原始檔的節點編號也不一樣。軟連結的大小就是指向路徑的大小

[root@centos7 data]# rm -rf *
[root@centos7 data]# cp /etc/fstab  f1
[root@centos7 data]# ll
total 4
-rw-r--r--. 1 root root 595 Aug 30 19:03 f1
[root@centos7 data]# ln -s f1 f1.link
[root@centos7 data]# ll -i
total 4
67 -rw-r--r--. 1 root root 595 Aug 30 19:03 f1
68 lrwxrwxrwx. 1 root root   2 Aug 30 19:04 f1.link -> f1

如果刪除/data目錄下的f1檔案,那麼f1.link指向的檔案會報錯


f1.link

[root@centos7 data]# rm -f f1
[root@centos7 data]# ll
total 0
lrwxrwxrwx. 1 root root 2 Aug 30 19:04 f1.link -> f1

當訪問f1.link檔案時,此時會提示找不到檔案或者目錄

[root@centos7 data]# cat f1.link 
cat: f1.link: No such file or directory

此時可以複製任意一個檔案到/data目錄下重新命名為f1即可

f1.link並不關心原始的檔案內容是什麼,只要檔名存在即可

[root@centos7 data]# cp /etc/fstab  f1
[root@centos7 data]# ll
total 4
-rw-r--r--. 1 root root 595 Aug 30 19:09 f1
lrwxrwxrwx. 1 root root   2 Aug 30 19:04 f1.link -> f1

軟連結的相對路徑問題
在建立軟連結時,原始檔案使用相對路徑時(例如f1)的路徑應該是相對於軟連結檔案的路徑,而不是當前工作目錄的路徑。相對路徑的好處是如果檔案被移動到別的目錄下,依然可以使用。

絕對路徑也是可以,但是建立軟連結通常都是使用相對路徑

[root@centos7 data]# rm -rf *
[root@centos7 data]# cp /etc/fstab f1
[root@centos7 data]# mkdir -p d1/d2
[root@centos7 data]# ln -s f1 d1/d2/f1.link

[root@centos7 data]# ll d1/d2/f1.link 
lrwxrwxrwx. 1 root root 2 Aug 30 18:48 d1/d2/f1.link -> f1

相對於當前工作目錄建立的軟連結是錯誤的

正確的姿勢應該是這樣的

[root@centos7 data]# rm -rf *
[root@centos7 data]# cp /etc/fstab f1
[root@centos7 data]# mkdir -p d1/d2
[root@centos7 data]# ln -s ../../f1 d1/d2/f1.link
[root@centos7 data]# ll d1/d2/f1.link 
lrwxrwxrwx. 1 root root 8 Aug 30 18:51 d1/d2/f1.link -> ../../f1

原始檔案相對路徑建立軟連結的正確方式

軟連結可以支援資料夾

[root@centos7 data]# rm -rf *
[root@centos7 data]# mkdir d1
[root@centos7 data]# ln -s d1 d1.link
[root@centos7 data]# ll
total 0
drwxr-xr-x. 2 root root 6 Aug 30 19:14 d1
lrwxrwxrwx. 1 root root 2 Aug 30 19:14 d1.link -> d1

軟連結是可以跨分割槽建立

/data和/opt是不同的分割槽 ,分別對應data分割槽和根分割槽

[root@centos7 data]# ln -s /data/f1 /opt/f1.link
[root@centos7 data]# ll !*
ll -s /data/f1 /opt/f1.link
4 -rw-r--r--. 1 root root 595 Aug 30 18:23 /data/f1
0 lrwxrwxrwx. 1 root root   8 Aug 30 18:25 /opt/f1.link -> /data/f1

如果修改/opt下的f1.link,那麼/data下的f1也會跟著變化。
修改/opt/f1.link

檢視/data/f1

軟連結的應用場景

在安裝mysql8時,預設安裝的目錄是/usr/local/mysql8.0.12,而在實際使用時通常會建立一個軟連結mysql,方便升級

這裡建立mysql8.0.12和mysql8.0.13的資料夾來模擬不同版本的mysql

[root@centos7 data]# cd /usr/local/
[root@centos7 local]# mkdir mysql8.0.12
[root@centos7 local]# ln -s mysql8.0.12/ mysql
[root@centos7 local]# ll
total 0
drwxr-xr-x. 2 root root  6 Apr 11  2018 bin
drwxr-xr-x. 2 root root  6 Apr 11  2018 etc
drwxr-xr-x. 2 root root  6 Apr 11  2018 games
drwxr-xr-x. 2 root root  6 Apr 11  2018 include
drwxr-xr-x. 2 root root  6 Apr 11  2018 lib
drwxr-xr-x. 2 root root  6 Apr 11  2018 lib64
drwxr-xr-x. 2 root root  6 Apr 11  2018 libexec
lrwxrwxrwx. 1 root root 12 Aug 30 19:28 mysql -> mysql8.0.12/
drwxr-xr-x. 2 root root 19 Aug 30 19:27 mysql8.0.12
drwxr-xr-x. 2 root root  6 Apr 11  2018 sbin
drwxr-xr-x. 5 root root 49 Aug 25 14:08 share
drwxr-xr-x. 2 root root  6 Apr 11  2018 src

如果mysql升級為mysql8.0.13,則刪除原有的mysql連結,然後新建一個連結指向mysql8.0.13即可

[root@centos7 local]# rm -rf mysql
[root@centos7 local]# mkdir mysql8.0.13
[root@centos7 local]# ln -s mysql8.0.13 mysql
[root@centos7 local]# ll
total 0
drwxr-xr-x. 2 root root  6 Apr 11  2018 bin
drwxr-xr-x. 2 root root  6 Apr 11  2018 etc
drwxr-xr-x. 2 root root  6 Apr 11  2018 games
drwxr-xr-x. 2 root root  6 Apr 11  2018 include
drwxr-xr-x. 2 root root  6 Apr 11  2018 lib
drwxr-xr-x. 2 root root  6 Apr 11  2018 lib64
drwxr-xr-x. 2 root root  6 Apr 11  2018 libexec
lrwxrwxrwx. 1 root root 11 Aug 30 19:30 mysql -> mysql8.0.13
drwxr-xr-x. 2 root root 19 Aug 30 19:27 mysql8.0.12
drwxr-xr-x. 2 root root  6 Aug 30 19:30 mysql8.0.13
drwxr-xr-x. 2 root root  6 Apr 11  2018 sbin
drwxr-xr-x. 5 root root 49 Aug 25 14:08 share
drwxr-xr-x. 2 root root  6 Apr 11  2018 src

如果要回退到老版本,則刪除現有連結,再新建mysql連結到mysql8.0.12即可。

刪除軟連結
在刪除軟連結時,如果軟連結指向的是一個目錄,並且目錄下包含有檔案,那麼軟連結後面跟/ 刪除時會將軟連結指向目錄下的檔案刪除,而不會刪除軟連結。

[root@centos7 local]# touch mysql8.0.12/f1.txt
[root@centos7 local]# touch mysql8.0.13/f2.txt
[root@centos7 local]# ll
total 0
drwxr-xr-x. 2 root root  6 Apr 11  2018 bin
drwxr-xr-x. 2 root root  6 Apr 11  2018 etc
drwxr-xr-x. 2 root root  6 Apr 11  2018 games
drwxr-xr-x. 2 root root  6 Apr 11  2018 include
drwxr-xr-x. 2 root root  6 Apr 11  2018 lib
drwxr-xr-x. 2 root root  6 Apr 11  2018 lib64
drwxr-xr-x. 2 root root  6 Apr 11  2018 libexec
lrwxrwxrwx. 1 root root 11 Aug 30 19:30 mysql -> mysql8.0.13
drwxr-xr-x. 2 root root 33 Aug 30 19:33 mysql8.0.12
drwxr-xr-x. 2 root root 20 Aug 30 19:33 mysql8.0.13
drwxr-xr-x. 2 root root  6 Apr 11  2018 sbin
drwxr-xr-x. 5 root root 49 Aug 25 14:08 share
drwxr-xr-x. 2 root root  6 Apr 11  2018 src
[root@centos7 local]# rm -rf mysql/
[root@centos7 local]# ll mysql8.0.13/
total 0

如果刪除軟連結,連結檔案是目錄,並且目錄下包含檔案,但是刪除軟連結時連結名後不加上/,則不會刪除軟連結指向目錄下的檔案,而刪除的是軟連結本身

[root@centos7 local]# ln -s mysql8.0.12 mysql
[root@centos7 local]# ll mysql8.0.12/
total 0
-rw-r--r--. 1 root root 0 Aug 30 19:33 f1.txt
[root@centos7 local]# rm -rf mysql
[root@centos7 local]# ll mysql8.0.12/
total 0
-rw-r--r--. 1 root root 0 Aug 30 19:33 f1.txt
[root@centos7 local]# ll
total 0
drwxr-xr-x. 2 root root  6 Apr 11  2018 bin
drwxr-xr-x. 2 root root  6 Apr 11  2018 etc
drwxr-xr-x. 2 root root  6 Apr 11  2018 games
drwxr-xr-x. 2 root root  6 Apr 11  2018 include
drwxr-xr-x. 2 root root  6 Apr 11  2018 lib
drwxr-xr-x. 2 root root  6 Apr 11  2018 lib64
drwxr-xr-x. 2 root root  6 Apr 11  2018 libexec
drwxr-xr-x. 2 root root 20 Aug 30 19:41 mysql8.0.12
drwxr-xr-x. 2 root root  6 Aug 30 19:34 mysql8.0.13
drwxr-xr-x. 2 root root  6 Apr 11  2018 sbin
drwxr-xr-x. 5 root root 49 Aug 25 14:08 share
drwxr-xr-x. 2 root root  6 Apr 11  2018 src

Linux中每個資料夾都有.和..用於表示當前目錄和上級目錄,因此建立資料夾時預設的連結數是2。

面試題-軟連結和硬連結的區別

  1. 本質不同:硬連結是同一個檔案多個不同的名字,而軟連結是不同的檔案,節點編號不一樣
  2. 硬連結不支援分割槽建立,而軟連結支援跨分割槽建立
  3. 硬連結不支援針對目錄建立,而軟連結支援
  4. 硬連結節點編號一樣,軟連結節點編號不一樣
  5. 硬連結是平等的,而軟連結是依賴原始檔案
  6. 連結數的增長數不一樣,硬連結建立時連結數會增長,而軟連結的連結數不會增長。
  7. 軟連結的原始檔案路徑相對於軟連結的相對路徑麼,而硬連結的原始路徑相對於當前工作目錄的相對路徑
  8. 軟連結的檔案型別是軟連結,而硬連結的檔案型別和原始檔案的型別一致
  9. 硬連結不支援資料夾,軟連結支援資料夾
  10. 刪除原始檔後,硬連結只是連結數減1,但是連結檔案訪問不受影響,軟連結的連結檔案無法訪問

由於連結接侷限性太多,因此日常運維使用的還是軟連結