0

in our bash scripts , we have many places in the code that need to capture only the disk that related to OS ( operation linux/RHEL system )

we are using Linux versions as 7.2/7.5/7.6/7.9 , and on most cases machines have additional disks that used to store data or DB servers that include disks with TB size etc

usually we used the following cli in order to capture the OS disk

os_disk=` lsblk -l | grep part | awk '{print $1}' | sed s'/[0-9]/ /g' | sort -u | head -1 `

It works when no additional parted disks are exists, but when we have additional disks that are parted as below example:

NAME             MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda                8:0    0   1.8T  0 disk /data/sdb
sdb                8:16   0   1.8T  0 disk /data/sdc
sdc                8:32   0   1.8T  0 disk /data/sdd
sdd                8:48   0   1.8T  0 disk /data/sde
sde                8:64   0   1.8T  0 disk
├─sde1             8:65   0 931.3G  0 part
└─sde2             8:66   0 931.7G  0 part
sdf                8:80   0   1.8T  0 disk /data/sdg
sdg                8:96   0   1.8T  0 disk /data/sdh
sdh                8:112  0   1.8T  0 disk /data/sdi
sdi                8:128  0   1.8T  0 disk /data/sdj
sdj                8:144  0   1.8T  0 disk /data/sdk
sdk                8:160  0   1.8T  0 disk /data/sdl
sdl                8:176  0   1.8T  0 disk /data/sdm
sdm                8:192  0   1.8T  0 disk /data/sdn
sdn                8:208  0   1.8T  0 disk /data/sdo
sdo                8:224  0 557.9G  0 disk
├─sdo1             8:225  0   500M  0 part /boot
└─sdo2             8:226  0 557.4G  0 part
  ├─VGPO-lvm_root 253:0    0   100G  0 lvm  /
  ├─VGPO-lvm_swap 253:1    0    16G  0 lvm  [SWAP]
  └─VGPO-lvm_var  253:2    0   100G  0 lvm  /var

then we get wrong results that OS disk is sde instead to get sdo

 os_disk=` lsblk -l | grep part | awk '{print $1}' | sed s'/[0-9]/ /g' | sort -u | head -1 `
 echo $os_disk
 sde

so in that case we need to find other approach that gives the OS disk , when machine could be VM machine or physical machine

2
  • You get the result you asked for. The first line containing part (head -1) is ├─sde1 8:65 0 931.3G 0 part.
    – K-attila-
    Commented Sep 2, 2022 at 10:09
  • Try this: lsblk -l|sed -n "/.*[[:space:]]*\/[[:space:]]*$/p"
    – K-attila-
    Commented Sep 2, 2022 at 10:20

2 Answers 2

2

You can look for the disk containing the partition mounted on a system mount point, e.g. /boot:

lsblk -ls | awk '$NF == "/boot" { m = 1; next } m && $NF == "disk" { print $1 ; exit}'

This also works for /:

lsblk -ls | awk '$NF == "/" { m = 1; next } m && $NF == "disk" { print $1 ; exit}'

This uses lsblk’s list mode (-l) to simplify parsing, and reverses the tree (-s) so that the parent disk appears after the partition we’re looking for.

2

Do you have the findmnt command? I've used findmnt to get the device for the root filesystem in a script:

findmnt -ensP -M /

Searches /etc/fstab and on my test machine produces:

TARGET="/" SOURCE="/dev/nvme0n1p1" FSTYPE="ext4" OPTIONS="rw,discard,errors=remount-ro,x-systemd.growfs"

These are the default output fields for the "list" format. My scripts defined a custom set of output fields, which also sets the order they're printed:

findmnt -ensP -o SOURCE,TARGET,FSTYPE,SIZE,UUID,LABEL -M /

Produces:

SOURCE="/dev/nvme0n1p1" TARGET="/" FSTYPE="ext4" SIZE="39.2G" UUID="1ca031f6-4004-4f8d-a861-532a0158c91f" LABEL=""

findmnt has many options, among which is --tree to produce a tree like your question's lsblk output.

The options I use above are:
-e - "evaluate" the values in certain fields, converting them to devices. (without -e my SOURCE field would have been SOURCE="UUID=1ca031f6-4004-4f8d-a861-532a0158c91f")
-n - no header line in output
-s - read /etc/fstab (or -m to read /etc/mtab)
-P - output in "Pair" format FIELD="VALUE" (I found this easier to parse in a shell script)
-M - Limit the output to the filesystem mounted on this mount point

There are a number of other options giving a lot of flexibility. For example, -t ext4 to limit the search to ext4 filesystems.

Final note: findmnt finds the info on mounted filesystems (via /etc/mtab), or ones listed in /etc/fstab (mounted or not). It can't find ones that aren't mounted and aren't in /etc/fstab. For that you need lsblk or possibly the old blkid.

1
  • 2
    findmnt --noheadings --output=SOURCE / Commented Sep 2, 2022 at 21:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .