¿Cómo obtener el nombre del dispositivo de bloqueo del nombre del dispositivo de partición?

13

Estoy buscando una forma portátil de obtener el nombre del dispositivo de bloque primario (por ejemplo /dev/sda) dado el nombre del dispositivo de partición (por ejemplo /dev/sda1). Sé que podría dejar caer el último personaje, pero eso no funcionaría en algunos casos:

  • Los lectores de tarjetas MMC suelen tener nombres similares /dev/mmcblk0, mientras que sus particiones tienen nombres similares /dev/mmcblk0p1(observe el extra p).
  • opcional: algunos dispositivos de bloque no tienen ninguna tabla de particiones y están formateados como una sola partición. En este caso, el dispositivo de partición y el dispositivo de bloque primario son iguales.

Los volúmenes LVM son una caldera de peces completamente diferente. No necesito apoyarlos en este momento, pero si tomarlos en cuenta requiere poco esfuerzo adicional, no me importaría.

Dmitry Grigoryev
fuente
¿Qué tan portátil? Mi portátil tiene la partición raíz en /dev/sd0apero no hay /dev/sd0dispositivo (hay un /dev/sd0c...)
thrig
@don_crissti, /dev/sda1y /dev/mmcblk0p1son específicos de Linux de todos modos. lsblkSin embargo, es relativamente reciente.
Stéphane Chazelas
lsblktambién usa los números de nodo del dispositivo para encontrar el correcto, en lugar de solo usar el nombre. Parece que la solución más simple para Linux y util-linux probablemente siempre estará disponible de todos modos.
ilkkachu
1
@don_crissti lsblk -dpno pkname $devnamepasó todas mis pruebas! Quizás deberías agregar una respuesta.
Dmitry Grigoryev
@thrig Bueno, sí, definitivamente esperaría que el script regrese /dev/sd0cen ese caso. ¿Las respuestas a continuación funcionan para usted?
Dmitry Grigoryev

Respuestas:

15

Si estás en Linux puedes usar lsblk(que es parte de util-linux):

lsblk -no pkname /dev/sda1
don_crissti
fuente
2
Mi lsblk( util-linux: 2.20.1, Ubuntu 14.04) no tiene la pknamecolumna, solo kname.
heemayl
3
@heemayl - que se añadió sólo hace cuatro años, por lo que no está disponible en distribuciones que utilizan versiones anteriores ...
don_crissti
$ lsblk -no pkname /dev/nvme0n1p3devuelve 7 líneas en mi sistema. Sí, esta partición está encriptada y contiene LVM, esta no es una situación trivial. No sé cómo se supone que debes elegir de forma confiable la línea correcta de un script.
elboulangero
16

Si un dispositivo es una partición de otro dispositivo /sys/class/block/$dev, contendrá un archivo llamado partition(cuyo contenido es el número de partición).

Si ese es el caso, puede obtener el nombre del dispositivo principal con:

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

O con zsh:

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

Ejemplo:

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

Los volúmenes LVM son completamente diferentes, no son particiones, excepto en el caso especial donde son un linearmapeo contiguo de un PV físico.

Si se encuentra en ese caso, puede obtener el nombre de ese PV con:

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

¿Dónde $devestá algo así dm-2(que puede obtener de "$(basename "$(readlink -f /dev/VG/LV)")").

Stéphane Chazelas
fuente
Acepté la respuesta de don_crissti porque resulta que la tengo lsblky la sintaxis es corta, pero reconozco que su respuesta es más genérica y portátil. ¡Gracias!
Dmitry Grigoryev