df命令在LUKS加密文件系统中的设备名显示差异
问题描述
当不带参数执行df命令时,显示的文件系统列表如下:
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
但是,当指定文件名(如/)时,对应挂载点的文件系统会显示为不同的名称:
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/luks-609eee17-f9f4-446d-b399-1d5a6d7ddb9c 293457920 85102812 208355108 30% /
用户想知道如何确保在两种情况下文件系统显示相同的名称。
技术解析
设备名称处理机制
这种差异源于df命令对以UUID结尾的设备名称的特殊处理:
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显示较长的设备名称而不是短名称。
解决方案
方法一:输出后处理
可以使用以下命令对输出进行后处理:
df . | awk '{ "readlink " $1 " > /dev/null && readlink -f " $1 | getline replacement; if (replacement != "") $1 = sprintf("%-" length($1) "s", replacement) } 1'
方法二:使用findmnt命令
使用findmnt命令代替df:
findmnt --df
产生类似于df的结果,但不会对UUID后缀的设备名称进行后处理,而:
findmnt --df -T /
工作方式类似于df /(并且适用于任何类型的文件,与df相同)。
方法三:使用df -P选项
使用df -P命令:
df -P
-P选项使用POSIX输出格式,但需要注意这不会影响显示的设备名称。
系统差异性
这种行为在不同系统上并不相同,具体取决于:
- 使用的发行版
- coreutils版本
- 是否使用LVM、LUKS
- 系统配置
在Debian系统上使用LUKS和LVM时,两种命令对于/的输出是相同的:/dev/mapper/myroot--vg-root。
总结
df命令在显示所有文件系统和指定具体文件时对设备名称的处理方式不同,特别是在涉及LUKS加密设备时。用户可以通过输出后处理、使用findmnt命令或创建自定义脚本来获得一致的设备名称显示。