I am writing an installation automation BASH script. I'd like to install the nvme-cli package only if an NVMe SSD is actually present.
I couldn't find a simple way to query the hardware (say, using lshw) to get a kind-of-yes-or-no answer.
Any of you can give a way to extract the specific answer from within a BASH script?
I'd like to use the case conditioning to either install it or not.
- 193,181
- 53
- 473
- 722
- 1,426
- 2
- 14
- 26
-
1Is there some reason to not install the package regardless? Its not big. And there may be a case where hardware gets upgraded later, after the installation. – Criggie May 31 '21 at 03:25
-
Are these physical hosts of various specs, or are you using virtual machines ? – Criggie May 31 '21 at 03:37
6 Answers
A directory test is sufficient:
(the path /sys/class/nvme is created by the module nvme. However, this does not say anything about the operational state of the drive(s) or even if a drive exists, though).
#!/bin/bash
if [[ -d /sys/class/nvme ]]; then
apt-get -y install nvme-cli
fi
Or, if you prefer using globbing to check for the existence of a file(s), a for-loop will have the advantage of avoiding a subshell:
shopt -s nullglob
for _ in /dev/nvme*; do
apt-get -y install nvme-cli; break
done
Also, if you can, you should avoid globbing as an argument, where there are alternatives, e.g., in this case, the use of echo or printf is preferable (which is, in reality, a loop construct).
shopt -s nullglob
if [[ -n $(echo /dev/nvme*) ]]; then
apt-get -y install nvme-cli
fi
Check to see if any nvme device files exist:
if ls /dev/nvme*
then
echo "Install NVME-CLI"
fi
- 3,564
- 2
- 5
- 22
-
1You might also want to ignore the output of ls with `ls /dev/nvme* &>/dev/null`. – Nonny Moose May 31 '21 at 20:54
dmesg | grep -q nvme
if [ $? = 0 ] ; then
apt install nvme-cli -y
fi
All of these solutions should work about the same; they're all testing to see if the kernel has found a NVME device in any way.
If the installer runs at boot, this is probably adequate. If the installer might run long after boot, then the first line would be better as:
grep -q nvme /var/log/dmesg
- 671
- 5
- 12
-
-
7Kernel message buffer is a ring buffer. If a lot of messages have been emitted (e.g. due to long uptime), they'll overwrite the older ones, and this method will give false negative. – Ruslan May 31 '21 at 13:17
-
-
1It's worth noting that, while this might work on Ubuntu, other linux setups might have access to dmesg restricted to the root user. So, if you're planning to run this on other distros, or if ubuntu changes kernel.dmesg_restrict, you might want to use a different approach. – Nonny Moose May 31 '21 at 20:53
Try using lsscsi:
NVMECOUNT=`lsscsi | grep nvme | wc -l`
if [ $NVMECOUNT -gt 1 ]
then
echo "Install NVME-CLI"
fi
- 162
- 5
-
1`lsscsi` isn't installed as default, it may seem a bit unnecessary to install one package to test if you need to install another. – May 31 '21 at 00:58
Check if the nvme driver is loaded
if grep -q nvme /proc/devices
then
echo "Install NVME-CLI"
fi
- 3,564
- 2
- 5
- 22
In some cases, free space is an issue, besides, i am a firm believer in not installing redundant packaged as a rule, so, eventually I went with:
NVMECOUNT=`lsblk | grep nvme | wc -l`
if [ $NVMECOUNT -gt 1 ]
then
apt -y install nvme-cli
fi
Thanks!
- 1,426
- 2
- 14
- 26
-
This should be the accepted answer, not mine. This is what worked for you. – Criggie May 31 '21 at 19:41