Jak uzyskać nazwę urządzenia blokowego z nazwy urządzenia partycji?

14

Szukam przenośnego sposobu na uzyskanie nazwy nadrzędnego urządzenia blokowego (np. /dev/sda) Biorąc pod uwagę nazwę urządzenia partycji (np /dev/sda1.). Wiem, że mogłem po prostu upuścić ostatnią postać, ale w niektórych przypadkach to nie zadziała:

  • Czytniki kart MMC zwykle mają nazwy takie jak /dev/mmcblk0, podczas gdy ich partycje mają nazwy takie jak /dev/mmcblk0p1(zauważ dodatkowe p).
  • opcjonalnie: niektóre urządzenia blokowe nie mają żadnej tabeli partycji i są sformatowane jako pojedyncza partycja. W takim przypadku urządzenie partycji i urządzenie nadrzędnego bloku są takie same.

Objętości LVM to zupełnie inny czajnik ryb. Nie muszę ich teraz wspierać, ale jeśli uwzględnienie ich wymaga niewielkiego dodatkowego wysiłku, nie miałbym nic przeciwko.

Dmitrij Grigoriew
źródło
Jak przenośny? Mój laptop ma partycję root, /dev/sd0aale nie ma /dev/sd0urządzenia (jest /dev/sd0c...)
thrig
@don_crissti /dev/sda1i /dev/mmcblk0p1są specyficzne dla Linuksa. lsblkjest stosunkowo nowy.
Stéphane Chazelas,
lsblkużywa również numerów węzłów urządzenia, aby znaleźć właściwy, zamiast po prostu używać nazwy. Wydaje się, że najprostsze rozwiązanie dla Linuksa i util-linux prawdopodobnie i tak będzie zawsze dostępne.
ilkkachu
1
@don_crissti lsblk -dpno pkname $devnameprzeszedł wszystkie moje testy! Być może powinieneś dodać odpowiedź.
Dmitrij Grigoryev,
@ thrig Cóż, tak, na pewno spodziewałbym się, że skrypt wróci /dev/sd0cw takim przypadku. Czy poniższe odpowiedzi działają dla Ciebie?
Dmitrij Grigoryev

Odpowiedzi:

16

Jeśli korzystasz z systemu Linux, możesz użyć lsblk(który jest częścią util-linux):

lsblk -no pkname /dev/sda1
don_crissti
źródło
2
Mój lsblk( util-linux: 2.20.1, Ubuntu 14.04) pknamepo prostu nie ma kolumny kname.
heemayl
3
@heemayl - został dodany zaledwie cztery lata temu, więc nie jest dostępny na dystrybucjach korzystających ze starszych wersji ...
don_crissti
$ lsblk -no pkname /dev/nvme0n1p3zwraca 7 wierszy w moim systemie. Tak, ta partycja jest zaszyfrowana i zawiera LVM, nie jest to trywialna sytuacja. Nie wiem, jak rzetelnie pobrać właściwą linię ze skryptu.
elboulangero,
16

Jeśli urządzenie jest partycją innego urządzenia, wówczas /sys/class/block/$devbędzie zawierać plik o nazwie partition(którego zawartość jest numerem partycji).

W takim przypadku możesz uzyskać nazwę urządzenia nadrzędnego za pomocą:

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

Lub z zsh:

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

Przykład:

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

Objętości LVM są całkowicie różne, nie są partycjami, z wyjątkiem specjalnego przypadku, w którym są one jednym ciągłym linearodwzorowaniem fizycznego PV.

W takim przypadku możesz uzyskać nazwę tego teledysku za pomocą:

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

Gdzie $devjest coś takiego dm-2(z czego można uzyskać "$(basename "$(readlink -f /dev/VG/LV)")").

Stéphane Chazelas
źródło
Zaakceptowałem odpowiedź don_crissti, ponieważ tak się lsblkskłada, a składnia jest krótka, ale potwierdzam, że twoja odpowiedź jest bardziej ogólna i przenośna. Dzięki!
Dmitry Grigoryev