Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm looking for a portable way to obtain parent block device name (e.g. /dev/sda) given the partition device name (e.g. /dev/sda1). I know I could just drop the last character, but that wouldn't work in some cases:

  • MMC card readers typically have names like /dev/mmcblk0, while their partitions have names like /dev/mmcblk0p1 (notice the extra p).
  • optional: some block devices don't have any partition table at all and are formatted as a single partition. In this case, partition device and parent block device are the same.

LVM volumes are a whole different kettle of fish. I don't need to support them right now, but if taking them into account requires little extra effort, I wouldn't mind.

share|improve this question
    
How portable? My laptop has its root partition on /dev/sd0a but there's no /dev/sd0 device (there is a /dev/sd0c...) – thrig yesterday
    
@don_crissti, /dev/sda1 and /dev/mmcblk0p1 are Linux-specific anyway. lsblk is relatively recent though. – Stéphane Chazelas yesterday
    
lsblk also uses the device node numbers to find the correct one, instead of just using the name. seems the simplest solution for Linux and util-linux would likely be always available anyway. – ilkkachu yesterday
    
@don_crissti lsblk -dpno pkname $devname passed all my tests! Perhaps you should add an answer. – Dmitry Grigoryev yesterday
    
@thrig Well yeah, I'd definitely expect the script to return /dev/sd0c in that case. Do the answers below work for you? – Dmitry Grigoryev 16 hours ago
up vote 7 down vote accepted

If you're on linux you could use lsblk (which is part of util-linux):

lsblk -no pkname /dev/sda1
share|improve this answer
1  
My lsblk (util-linux:2.20.1, Ubuntu 14.04) does not have the pkname column, just kname. – heemayl yesterday
3  
@heemayl - it was added only four years ago so not available on distros that use older releases... – don_crissti yesterday

If a device is a partition of another device then /sys/class/block/$dev will contain a file called partition (whose content is the partition number).

If that's the case, you can get the name of the parent device with:

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

Or with zsh:

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

Example:

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

LVM volumes are completely different, they are not partitions except in the special case where they are one contiguous linear mapping of a physical PV.

If you're in such a case, you can get the name of that PV with:

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

Where $dev is something like dm-2 (which you can obtain from "$(basename "$(readlink -f /dev/VG/LV)")").

share|improve this answer
    
I have accepted don_crissti's answer because I happen to have lsblk and the syntax is short, but I acknowledge that your answer is more generic and portable. Thanks! – Dmitry Grigoryev 16 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.