Як отримати ім'я блокового пристрою від імені пристрою перегородки?


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Хоча порівняно недавно.
Стефан Шазелас

lsblkтакож використовує номери вузлів пристрою, щоб знайти правильний, а не просто використовувати ім'я. Здається, найпростіше рішення для Linux і util-linux, швидше за все, завжди буде доступне.
ilkkachu

1
@don_crissti lsblk -dpno pkname $devnameпройшов усі мої тести! Можливо, вам слід додати відповідь.
Дмитро Григор'єв

@thrig Ну так, я б точно сподівався, що сценарій повернеться /dev/sd0cв такому випадку. Чи працюють відповіді нижче для вас?
Дмитро Григор’єв

Відповіді:


16

Якщо ви користуєтесь Linux, ви можете використовувати lsblk(що є частиною util-linux):

lsblk -no pkname /dev/sda1

2
У мого lsblk( util-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.

Якщо ви в такому випадку, ви можете отримати ім'я цього фотографії за допомогою:

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

Де $devщось подібне dm-2(що ви можете отримати "$(basename "$(readlink -f /dev/VG/LV)")").


Я прийняв відповідь don_crissti, тому що у мене трапляється, lsblkа синтаксис - короткий, але я визнаю, що ваша відповідь є більш загальною та портативною. Дякую!
Дмитро Григор'єв
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.