df 命令詳解:全稱、常用引數與輸出各列含義
df 命令是 disk free 的縮寫,用來檢視每個已掛載檔案系統的總容量、已用空間、可用空間和使用率。日常用 df -h 看空間,df -i 看 inode,df -hT 順帶顯示檔案系統型別;巡檢時不能只看百分比,還要看剩餘的絕對空間和增長速度。
df 命令是 disk free 的縮寫,字面意思是“磁碟剩餘空間”,屬於 GNU coreutils,幾乎所有 Linux 發行版都自帶。它的作用是列出每個已掛載的檔案系統用了多少、還剩多少。最常用的寫法是 df -h,-h 讓大小以 K、M、G、T 顯示:
df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 795M 1.6M 793M 1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv 98G 23G 70G 25% /
tmpfs 3.9G 0 3.9G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/sda2 2.0G 185M 1.6G 11% /boot
/dev/sda1 1.1G 6.2M 1.1G 1% /boot/efi
/dev/sdb1 3.6T 2.9T 532G 85% /data
tmpfs 795M 12K 795M 1% /run/user/1000
這是一台 Ubuntu 伺服器的範例輸出:根分割槽在 LVM 邏輯捲上,用了 25%;資料盤掛在 /data,用了 85%,還剩 532G。
df 是什麼的縮寫,能看什麼、看不到什麼
名字雖然叫 disk free,df 統計的其實是檔案系統的空間,而不是物理硬碟。它不逐個統計檔案,而是直接讀取檔案系統自己維護的計數,所以即使是幾十 TB 的分割槽也能瞬間出結果。也正因為如此,它只能看到已經掛載的檔案系統:插上了但沒掛載的硬碟、沒格式化的分割槽,df 裡都不會出現。幾個容易混用的命令分工如下:
| 想知道什麼 | 用哪個命令 |
|---|---|
| 每個分割槽總共多大、用了多少、還剩多少 | df -h |
| 某個目錄佔了多少空間 | du -sh 目錄 |
| 機器上有幾塊盤、怎麼分割槽,包括沒掛載的 | lsblk |
| 某個分割槽以什麼引數掛載,是不是隻讀 | findmnt 掛載點 |
輸出各列是什麼意思
| 列名 | 含義 | 看的時候注意 |
|---|---|---|
| Filesystem | 檔案系統的來源 | /dev/sda2 是普通分割槽;/dev/mapper/ubuntu--vg-ubuntu--lv 是 LVM 邏輯卷,名字裡的 -- 代表卷組名、邏輯卷名中的一個 -,即卷組 ubuntu-vg 下的邏輯卷 ubuntu-lv;tmpfs 是記憶體盤;overlay 是容器的檔案系統 |
| Size | 檔案系統總容量 | 是格式化後的容量,不是硬碟的標稱容量,見後文 |
| Used | 已用空間 | — |
| Avail | 普通使用者還能用的空間 | 不包括為 root 預留的部分 |
| Use% | 使用率 | 計算公式是 Used ÷(Used + Avail),小數部分一律進位 |
| Mounted on | 掛載點 | 判斷某個目錄落在哪個分割槽上 |
拿上面根分割槽那一行驗算一遍:23 + 70 = 93G,比 Size 的 98G 少了約 5G。這部分既不算已用,也不算可用,是 ext4 預設為 root 預留的 5% 空間(98G × 5% ≈ 4.9G),用來保證分割槽寫滿時 root 還能登入處理。使用率按 23 ÷ (23 + 70) ≈ 24.7% 計算,進位後顯示為 25%。-h 顯示的數字都經過取整,這樣驗算只能看個大概,要精確核對就用 df -k 看以 KB 為單位的原始數值。因為分母不含預留空間,所以 Use% 顯示 100% 時,普通使用者已經寫不進去,root 卻還能寫。
這個預留在根分割槽上很有用,在大容量資料盤上就有點浪費:3.6T 的 /data 按 5% 算,預留了 180G 左右。純資料分割槽可以把比例調低,例如改成 1%:
sudo tune2fs -l /dev/sdb1 | grep -i 'reserved block count' # 檢視當前預留的塊數
sudo tune2fs -m 1 /dev/sdb1 # 預留比例改為 1%,線上生效
XFS 沒有這種為 root 預留的空間,同樣的算式在 XFS 分割槽上,Used 加 Avail 基本等於 Size。根分割槽建議保持預設,不要改。
df 命令常用引數
| 引數 | 作用 | 範例 |
|---|---|---|
-h |
自動選擇單位,按 1024 進位 | df -h |
-H(--si) |
自動選擇單位,按 1000 進位,與硬碟標稱容量的口徑一致 | df -H |
-k、-BM、-BG |
固定以 1024 進位的 K、M、G 為單位輸出,便於比較和計算 | df -BG /data |
-T |
增加 Type 列,顯示 ext4、xfs、tmpfs 等型別 | df -hT |
-t 型別 |
只顯示指定型別,可以寫多次 | df -h -t ext4 -t xfs |
-x 型別 |
排除指定型別,可以寫多次 | df -h -x tmpfs -x devtmpfs |
-i |
顯示 inode 的用量,而不是空間 | df -i |
-l |
只顯示本地檔案系統,跳過 NFS 等網路掛載 | df -hl |
-a |
連同 proc、sysfs 這類偽檔案系統和重複的掛載一起顯示 | df -a |
-P |
按 POSIX 規定的格式輸出,列固定,老指令碼常用 | df -P |
--output=欄位 |
自己挑選要顯示的列 | 見下方範例 |
--total |
在末尾加一行合計 | df -h --total -x tmpfs |
| 路徑 | 只顯示這個路徑所在的檔案系統 | df -h /var/lib/mysql |
幾個實際用得上的組合:
# 只看真實磁碟:排除記憶體盤、容器層和 snap 軟體包的唯讀映象
df -hT -x tmpfs -x devtmpfs -x overlay -x squashfs
# 資料庫目錄在哪個分割槽上、還剩多少
df -h /var/lib/mysql
# 空間和 inode 使用率放在一張表裡
df -h --output=source,fstype,size,used,avail,pcent,ipcent,target -x tmpfs -x devtmpfs
# 指令碼里取根分割槽的可用空間,單位 KB
df -P / | awk 'NR==2 {print $4}'
--output 不能和 -i、-T、-P 同時使用,否則會報兩個選項互斥;要 inode 和型別,就把 ipcent、fstype 寫進欄位列表裡。可用的欄位有 source、fstype、itotal、iused、iavail、ipcent、size、used、avail、pcent、file、target。
df -i:inode 怎麼看
每個檔案和目錄都要佔用一個 inode。ext4 的 inode 總數在格式化時就定死了,小檔案特別多的分割槽,可能空間還剩一大半,inode 卻先用完,這時寫檔案同樣報 No space left on device。df -i 的輸出:
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/ubuntu--vg-ubuntu--lv 6553600 245872 6307728 4% /
/dev/sda2 131072 623 130449 1% /boot
/dev/sda1 0 0 0 - /boot/efi
/dev/sdb1 244187136 101245 244085891 1% /data
| 列名 | 含義 |
|---|---|
| Inodes | inode 總數 |
| IUsed | 已用的 inode,約等於這個分割槽上檔案和目錄的總數 |
| IFree | 剩餘可用的 inode |
| IUse% | inode 使用率 |
/boot/efi 顯示 0 和 - 是正常的,它是 FAT 格式的 EFI 分割槽,不使用 inode 機制。根分割槽的 6553600 個 inode,是 ext4 在常見大小(4 TiB 以下)的分割槽上預設每 16 KB 空間分配一個 inode 的結果。如果事先知道某個分割槽要存海量小檔案(比如圖片快取、郵件儲存),格式化時就可以加大 inode 數量:mkfs.ext4 -i 8192 /dev/sdc1 表示每 8 KB 分配一個,-N 引數則直接指定 inode 總數。XFS 的 inode 按需分配,一般不會先於空間用盡。
巡檢時看 df:關注哪些閾值
只看 Use% 容易誤判:同樣是 85%,20G 的根分割槽只剩 3G 左右,一個失控的日誌幾個小時就能寫滿;20T 的資料盤還剩 3T,可能夠用幾個月。所以巡檢時按分割槽的用途分別看:
| 掛載點 | 為什麼要盯 | 參考閾值(按業務調整) |
|---|---|---|
/ |
寫滿後日志寫不進、服務異常,嚴重時無法登入 | 80% 預警,90% 必須處理 |
/boot |
分割槽小,滿了以後新核心裝不上,apt 升級報錯 | 80%,或可用空間少於 300M |
/var、/var/log(單獨分割槽時) |
日誌、資料庫、容器映象都在這裡增長 | 80% 預警,90% 處理 |
資料盤(如 /data) |
容量大,百分比不敏感 | 按增長速度算剩餘天數,少於 30 天就擴容或清理 |
/dev/shm、/run 等 tmpfs |
佔的是記憶體,不是磁碟 | 持續增長就查是哪個程式寫的 |
| 所有分割槽的 IUse% | 會話檔案、快取、郵件佇列等小檔案堆積 | 80% |
剩餘天數的演算法:假設 /data 一週前已用 2.8T,今天 2.9T,一週增長約 100G,每天約 15G;還剩 532G,532 ÷ 15 ≈ 35 天。超過 30 天的餘量,留出了採購硬碟、安排上架的時間。
把檢查寫成指令碼,只輸出超過閾值的分割槽,沒有輸出就說明一切正常:
#!/bin/bash
# 列出空間或 inode 使用率達到閾值的檔案系統
LIMIT=80
timeout 10 df -h --output=target,pcent,ipcent,avail \
-x tmpfs -x devtmpfs -x overlay -x squashfs \
| awk -v limit="$LIMIT" 'NR==1 || $2+0 >= limit || $3+0 >= limit'
awk 裡的 $2+0 會把 85% 這樣的字串轉成數字 85,- 會被當成 0。timeout 10 防止遇到失聯的網路掛載時指令碼一直卡住。另外,df 不會告訴你哪個分割槽變成了唯讀,磁碟出錯後核心把分割槽自動改成唯讀的情況,巡檢時用 findmnt -O ro -t ext4,xfs 單獨查一遍,有輸出就要看看是不是該唯讀的。
幾個看起來不對的 df 輸出
- 買的是 4 TB 硬碟,df 只顯示 3.6T。硬碟廠商按 1000 進位,4 TB 約等於 4×10¹² 位元組;
df -h按 1024 進位,換算下來只有約 3.64 TiB,再扣掉格式化時 inode 表、日誌等後設資料佔用的空間,就是 3.6T 左右。用df -H看會更接近標稱值。 - 一串
/dev/loop開頭的裝置,使用率全是 100%。裝過 snap 軟體的 Ubuntu 上常見,它們是 snap 軟體包的唯讀映象(squashfs 格式),本來就是滿的,加-x squashfs隱藏即可。 - 裝了 Docker 後多出很多 overlay。每個執行中的容器都有一個 overlay 掛載點,顯示的容量和使用率與
/var/lib/docker所在的分割槽完全相同,它們是同一塊空間的不同檢視,不是額外的空間,加-x overlay隱藏。 - tmpfs 的 Size 加起來超過了記憶體。tmpfs 的 Size 只是上限,實際只佔已寫入內容那麼多的記憶體,幾個 tmpfs 的上限加起來超過實體記憶體並不矛盾。
在管理系統裡怎麼落地
df 只回答“掛上去的空間用了多少”,回答不了“這台機器一共有幾塊盤”。巡檢中常見的一種浪費是:客戶加購的資料盤裝上了,卻一直沒分割槽掛載,df 裡看不到,lsblk 裡卻躺著一塊 3.6T 的 sdc。單台機器上用 lsblk -dno NAME,SIZE,MODEL 列出所有物理盤,再和 df 裡出現的裝置對照就能發現。
機器一多,靠登入逐台對照就不現實了。Toplink DCIM 的機櫃與資產透過下發到伺服器的採集指令碼拿到真實的硬碟、CPU 和記憶體資訊,每一次採集結果都存檔;台帳里人工登記的配置與實際探測到的配置並列儲存。df 負責看使用率,資產台帳負責看硬體配置,兩邊對照,就能找出有盤沒用、配置被改過或者硬碟被換過的機器。
常見問題
df 和 du 有什麼區別?
df 直接向檔案系統要統計數字,幾乎瞬間出結果,看的是整個分割槽;du 逐個遍歷檔案累加大小,看的是某個目錄。兩者對不上時,最常見的原因是檔案已被刪除但仍有程序開啟著,用 lsof +L1 可以找出來。
df 命令卡住不動怎麼辦?
多半是掛著一個已經失聯的 NFS 等網路檔案系統,df 在等它回應。按 Ctrl+C 中斷後,用 df -hl 只看本地檔案系統,或者用 timeout 10 df -h 限定等待時間,再用 findmnt -t nfs,nfs4 找出是哪個掛載點出了問題。
Windows 上有 df 命令嗎?
沒有。PowerShell 裡用 Get-Volume 可以看到每個卷的總容量(Size)和剩餘空間(SizeRemaining),用 Get-PSDrive -PSProvider FileSystem 也能看到各盤的已用和可用空間。