Issue
In my current system, I have 3 SSDs, sda, sdb and sdc. The OS is installed in sdc. I am trying to extract the SSDs without the OS installed in it. So, this command
echo $(eval $(lsblk -oMOUNTPOINT,PKNAME -P | grep 'MOUNTPOINT="/"'); echo $PKNAME | sed 's/[0-9]*$//')
returns sdc. But if I want the drive without OS, how should I modify the above command?
grep 'MOUNTPOINT!="/"' doesn't return anything.
The bash script provided by Renaud works as expected on systems with raw drives. In case, if the system has LVM partitions then it returns only dm-1. How to handle this case? To get the correct SSD name on either raw or LVM systems? On the LVM system, lsblk returns. The expected output is sdb
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 1.8T 0 disk
├─sda1 8:1 0 512M 0 part /boot/efi
├─sda2 8:2 0 1G 0 part /boot
└─sda3 8:3 0 1.8T 0 part
├─ubuntu--vg-ubuntu--lv-real
│ 253:1 0 880G 0 lvm
│ ├─ubuntu--vg-ubuntu--lv 253:2 0 880G 0 lvm /
│ └─ubuntu--vg-clean 253:4 0 880G 0 lvm
└─ubuntu--vg-clean-cow 253:3 0 400G 0 lvm
└─ubuntu--vg-clean 253:4 0 880G 0 lvm
sdb 8:16 0 1.8T 0 disk
On the raw drive, lsblk returns
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 223.6G 0 disk
sdb 8:16 0 465.8G 0 disk
├─sdb1 8:17 0 2G 0 part
└─sdb2 8:18 0 463.8G 0 part
sdc 8:32 0 232.9G 0 disk
├─sdc1 8:33 0 156M 0 part /boot/efi
├─sdc2 8:34 0 26.7G 0 part /boot
├─sdc3 8:35 0 182.7G 0 part /
└─sdc4 8:36 0 23.4G 0 part [SWAP]
Here the expected output is sda or sdc.
Solution
grep
has a -v
option to print only non-matching lines. So:
lsblk -oMOUNTPOINT,PKNAME -P | grep -v 'MOUNTPOINT="/"'
should exclude this drive. But note that if you have more than one other drive the rest of your script will not work as you would like. Only the last drive will be considered because it overrides the others. A loop would probably be closer to your needs:
while IFS= read -r line; do
eval "$line"
sed 's/[0-9]*$//' <<< "$PKNAME"
done < <(lsblk -oMOUNTPOINT,PKNAME -P | grep -v 'MOUNTPOINT="/"')
Answered By - Renaud Pacalet