如何从分区设备名称中获取块设备名称?

Dmi*_*yev 17 partition shell-script block-device

我正在寻找一种可移植的方式来获取/dev/sda给定分区设备名称(例如/dev/sda1)的父块设备名称(例如)。我知道我可以删除最后一个字符,但在某些情况下不起作用:

  • MMC 读卡器的名称通常类似于/dev/mmcblk0,而它们的分区名称则类似于/dev/mmcblk0p1(注意额外的p)。
  • 可选:一些块设备根本没有任何分区表,并且被格式化为单个分​​区。在这种情况下,分区设备和父块设备是相同的。

LVM 卷是完全不同的鱼。我现在不需要支持他们,但如果考虑到他们需要一点额外的努力,我不会介意。

Sté*_*las 20

如果一个设备是另一个设备的分区,那么/sys/class/block/$dev将包含一个名为partition(其内容是分区号)的文件。

如果是这种情况,您可以使用以下命令获取父设备的名称:

basename "$(readlink -f "/sys/class/block/$dev/..")"
Run Code Online (Sandbox Code Playgroud)

或与zsh

echo /sys/class/block/$dev(:A:h:t)
Run Code Online (Sandbox Code Playgroud)

例子:

$ dev=sda1
$ basename "$(readlink -f "/sys/class/block/$dev/..")"
sda
$ dev=nbd0p1
$ basename "$(readlink -f "/sys/class/block/$dev/..")"
nbd0
Run Code Online (Sandbox Code Playgroud)

LVM 卷完全不同,它们不是分区,除非它们是linear物理 PV 的一个连续映射的特殊情况。

如果您遇到这种情况,您可以使用以下命令获取该 PV 的名称:

ls "/sys/class/block/$dev/slaves"
Run Code Online (Sandbox Code Playgroud)

哪里$dev是一样的东西dm-2(你可以从获得"$(basename "$(readlink -f /dev/VG/LV)")")。


don*_*sti 19

如果您使用的是 linux,则可以使用lsblk(这是 的一部分util-linux):

lsblk -no pkname /dev/sda1
Run Code Online (Sandbox Code Playgroud)

  • @heemayl - 它是 _only_ [四年前](http://git.kernel.org/cgit/utils/util-linux/util-linux.git/commit/?id=310c06035630a83dddfafaca55e5de8d0971a20c) 所以在发行版上不可用使用旧版本... (3认同)
  • 我的 `lsblk`(`util-linux`:2.20.1,Ubuntu 14.04)没有 `pkname` 列,只有 `kname`。 (2认同)
  • `$ lsblk -no pkname /dev/nvme0n1p3` 在我的系统上返回 7 行。是的,这个分区是加密的,并且包含 LVM,这不是一个简单的情况。我不知道你应该如何可靠地从脚本中选取正确的行。 (2认同)