不同 Linux 發行版中「df」的輸出格式不同

不同 Linux 發行版中「df」的輸出格式不同

在 Ubuntu 中此命令的輸出

df --exclude={tmpfs,devtmpfs,squashfs,overlay} | sed -e /^Filesystem/d | awk '{print $6 " " $1 " " $3 " " $4 " " $5}'

是:

/ /dev/mapper/dockerVG-rootLV 8110496 40591632 17%
/dockerssd /dev/mapper/ssdVG-ssdLV 214133656 274642488 44%
/dockerhdd /dev/mapper/hddVG-hddLV 83278236 1385191240 6%
/var/lib/docker /dev/mapper/hddVG-dockerLV 76046204 412729940 16%

這就是我所需要的。

在 CentOS 6 上我得到以下輸出:

 /dev/mapper/vg_rproxy-lv_root
 51475068 43192316 12% /
/boot /dev/sda1 82688 379364 18%
 /dev/mapper/vg_rproxy-lv_home
 77349888 73119692 1% /home

一團糟。

CentOS 6 的完整輸出:

$ df
Filesystem           1K-blocks    Used Available Use% Mounted on
/dev/mapper/vg_rproxy-lv_root
                      51475068 5661336  43192292  12% /
tmpfs                   957140       0    957140   0% /dev/shm
/dev/sda1               487652   82688    379364  18% /boot
/dev/mapper/vg_rproxy-lv_home
                      77349888  294352  73119692   1% /home

問題是什麼?我該如何修復它?

答案1

太長了;博士

使用df -P


完整答案

/dev/mapper/vg_rproxy-lv_root/dev/mapper/vg_rproxy-lv_home是相對較長的字串。它出現df在CentOS中決定將它們的條目分成兩行,當您想要進一步解析輸出時,這會破壞邏輯。

在狹窄的終端中,這可能是一件好事,即使水平空間有限,也可以創建半列的人類可讀輸出。我希望在df寫入非 tty(在您的情況下為管道)時不要發生這種情況。

或許 dfFilesystem在 Ubuntu 中,如果列中的條目很長,則行為類似;也許你只是沒有經歷過這一點,因為你的時間相對較短。我不知道,這並不重要。重要的是dfPOSIX 工具並且應該遵循規格。但規範明確指出:

歷史df實現的預設輸出差異很大。因此,有必要以寬鬆的方式描述預設輸出,以適應所有已知的歷史實現,並添加可移植選項 ( -P) 以以可移植格式提供資訊。

關於該選項:

-P
以 STDOUT 部分中所述的格式產生輸出。

最後是 STDOUT 部分的相關部分(重點是我的):

此實作可以調整標題行和各個資料行的間距,以便資訊以有序的列呈現。

剩餘輸出-P應包括每個指定檔案系統的一行信息。這些行的格式應如下:

"%s %d %d %d %d%% %s\n", <file system name>, <total space>,
    <space used>, <space free>, <percentage used>,
    <file system root>

所以df允許輸出任何內容,除非您使用-P.如果沒有-P一些實作df可能會產生可預測和可解析的輸出,其他的…則不會產生那麼多。他們的行為可能會或可能不會被充分記錄。因此,一般來說,在解析輸出時應df始終使用-P.

只需添加-P可能就足以解決您的特定問題。

註釋-P僅控制格式。整體 POSIX 規範僅適用於 POSIX 語言環境。此外,現代實作預設為512df傾向於使用 1024 位元組區塊,而 POSIX 規定預設值為 512 dfPOSIXLY_CORRECT可移植的是,您可以使用-k.

這是一個可移植的命令,可以產生(幾乎)可解析的輸出:

LC_ALL=POSIX df -Pk

我認為幾乎可以解析,因為Filesystem列中的條目可能包含空格;儘管在配置合理的作業系統中它們不會。

您可以省略LC_ALL=POSIX並仍然獲得預期結果,但一般來說它應該用於解析。例如,在我的波蘭語言環境中,您sed -e /^Filesystem/d無法完成其工作,因為我從我的df.LC_ALL=POSIX解決這個問題。還是我的個人的偏好是不依賴標頭中的任何內容。我會使用sed 1dtail -n +2;或將任務委託給awk,因為awk它已經在您的管道中。這將是:

LC_ALL=POSIX df -Pk --exclude={tmpfs,devtmpfs,squashfs,overlay} \
| awk 'NR>1 {print $6 " " $1 " " $3 " " $4 " " $5}'

最後--exclude=不是一個便攜式選項。顯然它在兩個系統中都適用,但在其他系統中可能不起作用。

相關內容