解密df命令在不同参数下显示不同文件系统名称的原因

本文深入分析了在CentOS系统中使用df命令时,无参数和指定文件名参数情况下显示不同文件系统名称的技术原因,涉及LUKS加密、设备符号链接处理和findmnt替代方案。

df命令显示不同文件系统名称的技术解析

问题描述

当执行不带参数的df命令时,显示的文件系统列表如下:

1
2
3
4
5
6
7
8
Filesystem     1K-blocks     Used Available Use% Mounted on
devtmpfs         8112420        0   8112420   0% /dev
tmpfs            8123692     5732   8117960   1% /dev/shm
tmpfs            8123692    11908   8111784   1% /run
tmpfs            8123692        0   8123692   0% /sys/fs/cgroup
/dev/dm-1      293457920 85102676 208355244  29% /
/dev/sda1        1038336   192912    845424  19% /boot
tmpfs            1624740        0   1624740   0% /run/user/0

但当指定文件名(如/)时,对应挂载点的文件系统却显示为不同的名称:

1
2
Filesystem                                            1K-blocks     Used Available Use% Mounted on
/dev/mapper/luks-609eee17-f9f4-446d-b399-1d5a6d7ddb9c 293457920 85102812 208355108  30% /

技术原因分析

设备名称的特殊处理

这种差异源于df命令对以UUID结尾的设备名称的特殊处理机制。在df源代码中存在以下逻辑:

1
2
3
if (process_all
    && has_uuid_suffix (dev_name)
    && (resolved_dev = canonicalize_filename_mode (dev_name, CAN_EXISTING)))

相关代码注释解释道:

在某些系统上,dev_name可能是长命名符号链接,如/dev/disk/by-uuid/828fc648-9f30-43d8-a0b1-f7196a2edb66,指向更短且更有用的名称如/dev/sda1。它也可能看起来像/dev/mapper/luks-828fc648-9f30-43d8-a0b1-f7196a2edb66并指向/dev/dm-0。当process_all为true且dev_name是以UUID结尾的符号链接时,使用解析后的名称代替。

行为限制

这种设备名称处理仅在显示所有设备时发生,即当df不带参数调用时(选项除外)。此外,此处理无法禁用,因此无法要求无参数的df显示较长的设备名称而不是短名称。

解决方案

输出后处理

要在两种情况下获得相似的行为,可以对输出进行后处理:

1
df . | awk '{ "readlink " $1 " > /dev/null && readlink -f " $1 | getline replacement; if (replacement != "") $1 = sprintf("%-" length($1) "s", replacement) } 1'

使用findmnt替代

使用findmnt命令代替df

1
findmnt --df

产生类似于df的结果,但不对UUID后缀的设备名称进行后处理,且:

1
findmnt --df -T /

工作方式类似于df /(并且适用于任何类型的文件,与df相同)。

使用df -P选项

使用df -P命令:

1
df -P

这是一个格式说明符,虽然不会影响显示的设备名称,但提供符合POSIX标准的输出格式。

系统差异性

这种行为并非在所有系统上都相同,具体取决于:

  • 使用的发行版
  • coreutils版本
  • 是否使用LVM、LUKS
  • 系统配置

在具有LUKS和LVM的Debian系统上,两种命令对于/的输出结果是相同的,都显示为:/dev/mapper/myroot--vg-root

总结

这种差异是特定于系统设置的正常行为,源于df命令对设备符号链接的智能处理机制。用户可以通过后处理、使用findmnt命令或创建自定义脚本来实现一致的显示效果。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计