在 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
无法正常工作,因为我从我的 中获得了波兰语术语“文件系统” df
。LC_ALL=POSIX
解决了这个问题。我的个人的偏好是不依赖标题中的任何内容。我会使用sed 1d
或tail -n +2
;或者将任务委托给awk
,因为awk
已经在你的管道中。这将是:
LC_ALL=POSIX df -Pk --exclude={tmpfs,devtmpfs,squashfs,overlay} \
| awk 'NR>1 {print $6 " " $1 " " $3 " " $4 " " $5}'
最后--exclude=
不是一个可移植的选项。显然它在这两个系统中都适用,但它可能不适用于其他系统。