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


14

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

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

LVM的体积完全不同。我现在不需要支持他们,但是如果考虑到他们需要很少的额外努力,我也不会介意。


如何便携?我的笔记本电脑上有其根分区,/dev/sd0a但没有/dev/sd0设备(有一个/dev/sd0c...)
发狂

@don_crissti,/dev/sda1并且始终/dev/mmcblk0p1是特定于Linux的。lsblk虽然是相对较新的。
斯特凡Chazelas

lsblk还使用设备节点号来查找正确的节点号,而不仅仅是使用名称。似乎最简单的Linux和util-linux解决方案始终可以使用。
ilkkachu

1
@don_crissti lsblk -dpno pkname $devname通过了我所有的测试!也许您应该添加答案。
德米特里·格里戈里耶夫

@thrig是的,/dev/sd0c在这种情况下,我绝对希望脚本返回。以下答案对您有用吗?
德米特里·格里戈里耶夫

Answers:


16

如果您使用的是Linux,则可以使用lsblk(属于util-linux):

lsblk -no pkname /dev/sda1

2
我的lsblkutil-linux:2.20.1,Ubuntu 14.04)没有该pkname列,而仅此列kname
heemayl

3
@heemayl-它仅在 四年前添加,因此在使用较旧版本的发行版中不可用...
don_crissti

$ lsblk -no pkname /dev/nvme0n1p3在我的系统上返回7行。是的,此分区是加密的,并且包含LVM,这并非微不足道的情况。我不知道您应该如何可靠地从脚本中选择正确的行。
elboulangero

16

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

在这种情况下,您可以通过以下方式获取父设备的名称:

basename "$(readlink -f "/sys/class/block/$dev/..")"

或搭配zsh

echo /sys/class/block/$dev(:A:h:t)

例:

$ dev=sda1
$ basename "$(readlink -f "/sys/class/block/$dev/..")"
sda
$ dev=nbd0p1
$ basename "$(readlink -f "/sys/class/block/$dev/..")"
nbd0

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

如果遇到这种情况,可以通过以下方式获取该PV的名称:

ls "/sys/class/block/$dev/slaves"

哪里$dev有类似的东西dm-2(您可以从中获得"$(basename "$(readlink -f /dev/VG/LV)")")。


我接受don_crissti的答案是因为我碰巧拥有它lsblk,并且语法很短,但是我承认您的答案更加通用和可移植。谢谢!
德米特里·格里戈里耶夫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.