不同 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(在您的情况下是管道)时不要发生这种情况。

或许 df如果列中的条目Filesystem很长,Ubuntu 中的行为类似;也许你只是没有遇到这种情况,因为你的条目相对较短。我不知道,这并不重要。重要的是它df是一个 POSIX 工具,应该遵循规范。但规范中明确指出:

历史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 语言环境。此外,的现代实现df往往默认使用 1024 字节块,而 POSIX 规定默认值为 512。在我的 Debian 10 中,df当在环境中设置时,GNU coreutils 会恢复为 POSIX 默认值POSIXLY_CORRECT。您可以用 强制使用 1024 字节块-k

这是一个可移植的命令,可产生(几乎)可解析的输出:

LC_ALL=POSIX df -Pk

几乎可解析,因为Filesystem我认为列中的条目可能包含空格;尽管在合理配置的操作系统中它们不包含空格。

您可能省略它LC_ALL=POSIX,但仍然会得到预期的结果,但一般来说,它应该在那里进行解析。例如,在我的波兰语言环境中,您的命令sed -e /^Filesystem/d无法正常工作,因为我从我的 中获得了波兰语术语“文件系统” dfLC_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=不是一个可移植的选项。显然它在这两个系统中都适用,但它可能不适用于其他系统。

相关内容