Comment obtenir le nom du périphérique de bloc à partir du nom du périphérique de partition?

13

Je cherche un moyen portable pour obtenir le nom du périphérique de bloc parent (par exemple /dev/sda) étant donné le nom du périphérique de partition (par exemple /dev/sda1). Je sais que je pourrais simplement supprimer le dernier caractère, mais cela ne fonctionnerait pas dans certains cas:

  • Les lecteurs de cartes MMC ont généralement des noms comme /dev/mmcblk0, tandis que leurs partitions ont des noms comme /dev/mmcblk0p1(notez le supplément p).
  • facultatif: certains périphériques de bloc n'ont pas de table de partition et sont formatés comme une seule partition. Dans ce cas, le périphérique de partition et le périphérique de bloc parent sont identiques.

Les volumes LVM sont une toute autre marmite de poisson. Je n'ai pas besoin de les soutenir pour le moment, mais si les prendre en compte nécessite peu d'efforts supplémentaires, cela ne me dérangerait pas.

Dmitry Grigoryev
la source
Comment portable? Mon ordinateur portable a sa partition racine /dev/sd0amais il n'y a pas d' /dev/sd0appareil (il y a un /dev/sd0c...)
thrig
@don_crissti, /dev/sda1et /dev/mmcblk0p1sont de toute façon spécifiques à Linux. lsblkest relativement récent cependant.
Stéphane Chazelas
lsblkutilise également les numéros de nœud de périphérique pour trouver le bon, au lieu d'utiliser simplement le nom. semble que la solution la plus simple pour Linux et util-linux serait probablement toujours disponible de toute façon.
ilkkachu le
1
@don_crissti a lsblk -dpno pkname $devnameréussi tous mes tests! Vous devriez peut-être ajouter une réponse.
Dmitry Grigoryev
@thrig Eh bien oui, je m'attendrais certainement à ce que le script revienne /dev/sd0cdans ce cas. Les réponses ci-dessous vous conviennent-elles?
Dmitry Grigoryev

Réponses:

15

Si vous êtes sous Linux, vous pouvez utiliser lsblk(qui fait partie de util-linux):

lsblk -no pkname /dev/sda1
don_crissti
la source
2
Mon lsblk( util-linux: 2.20.1, Ubuntu 14.04) n'a pas la pknamecolonne, juste kname.
heemayl
3
@heemayl - il a été ajouté il y a seulement quatre ans, donc non disponible sur les distributions qui utilisent des versions plus anciennes ...
don_crissti
$ lsblk -no pkname /dev/nvme0n1p3renvoie 7 lignes sur mon système. Oui, cette partition est cryptée et contient LVM, ce n'est pas une situation banale. Je ne sais pas comment vous êtes censé récupérer de manière fiable la bonne ligne d'un script.
elboulangero
16

Si un périphérique est une partition d'un autre périphérique, il /sys/class/block/$devcontiendra un fichier appelé partition(dont le contenu est le numéro de partition).

Si tel est le cas, vous pouvez obtenir le nom du périphérique parent avec:

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

Ou avec zsh:

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

Exemple:

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

Les volumes LVM sont complètement différents, ils ne sont pas des partitions, sauf dans le cas spécial où ils constituent un linearmappage contigu d'un PV physique.

Si vous êtes dans un tel cas, vous pouvez obtenir le nom de ce PV avec:

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

$devest quelque chose comme dm-2(que vous pouvez obtenir "$(basename "$(readlink -f /dev/VG/LV)")").

Stéphane Chazelas
la source
J'ai accepté la réponse de don_crissti parce que je l'ai fait lsblket que la syntaxe est courte, mais je reconnais que votre réponse est plus générique et portable. Merci!
Dmitry Grigoryev