Reputation: 765
How do I compare bash command output and use IF ELSE block to do something.
I am trying to capture the bash command output in CMD variable and if the variable is empty / zero, then output that the binary/feature is missing. Pretty basic.
In the below code, the second if else
# Check if the CPU supports KVM
cmd=$(grep -Eiw 'vmx|svm' /proc/cpuinfo)
if [[ $cmd -ne 0 ]];then
echo "CPU on this machine does not support KVM. Check documentation please"
fi
#!/bin/bash
# Check if KVM kernel modules are installed.
cmd=$(lsmod | awk '{print $1}' | grep -Eiw 'kvm\|kvm_intel\|kvm_amd')
if [[ $cmd -ne 0 ]];then
echo "KVM kernel modules kvm or kvm_[intel|amd] missing. Use modprobe to load them please"
fi
# Check if the CPU supports KVM
cmd=$(grep -Eiw 'vmx|svm' /proc/cpuinfo)
if [[ $cmd -ne 0 ]];then
echo "CPU on this machine does not support KVM. Check documentation please"
fi
Instead of just checking the condition, the script is printing the command output (/proc/cpuinfo), I just want it to print the echo line but not the command output.
Upvotes: 1
Views: 1036
Reputation: 765
Thank you for your answers.
Many of you suggested using exit code which maybe the answer but I was specific about checking if the output result stored in the variable is an empty string or non-empty string and the [[ ]] test condition should not output to STD-OUT, just do a comparison without outputting anything to the terminal.
Second, I didn't want to use -q as it exits with zero status , not only for any match found but also for errors encountered.
Thirdly, I didn't use egrep as it is non-standard and deprecated [Ref:http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html]
Lastly, using -i and -w is redundant as the modules will be in lowercase and awk is doing the same as -w [Agreed] but just wanted to avoid assumptions esp that it will always be lowercase.
My Solution: cmd=$(grep -Eiw 'vmx|svm' /proc/cpuinfo) [[ -z "$cmd" ]] && echo "error: :CPU does not support KVM. Check documentation." && exit 1
-z does not output the return string to the terminal and just tells if the string is empty or non-empty.
Upvotes: 1
Reputation: 141200
You should check command exit status, not it's output.
#!/bin/bash
# Check if KVM kernel modules are installed.
if ! lsmod | awk '{print $1}' | grep -q -Eiw 'kvm|kvm_intel|kvm_amd'; then
echo "KVM kernel modules kvm or kvm_[intel|amd] missing. Use modprobe to load them please"
fi
# Check if the CPU supports KVM
if ! grep -q -Eiw 'vmx|svm' /proc/cpuinfo; then
echo "CPU on this machine does not support KVM. Check documentation please"
fi
or
#!/bin/bash
# Check if KVM kernel modules are installed.
lsmod | awk '{print $1}' | grep -q -Eiw 'kvm\|kvm_intel\|kvm_amd'
ret=$?
if ((ret != 0)); then
echo "KVM kernel modules kvm or kvm_[intel|amd] missing. Use modprobe to load them please"
fi
# Check if the CPU supports KVM
grep -q -Eiw 'vmx|svm' /proc/cpuinfo
ret=$?
if ((ret != 0)); then
echo "CPU on this machine does not support KVM. Check documentation please"
fi
Also decide if you use grep 'vmx\|svm'
or grep -E 'vmx|svm'
. Escaping \|
in -E
will parse |
as literal character. Here bashfaq How can I store the return value and/or output of a command in a variable? is a good bash introduction.
Also the grep -Eiw
looks a bit strange. Are you really looking for a modules named KvM_InTeL
or kVM_INteL
or kVm_InTeL
? There is only one module name, it's lowercase - kvm
, kvm_intel
, kvm_amd
. Also using -w
is irrelevant - lsmod | awk '{print $1}'
output is already one per line. I would just go with grep 'kvm\|kvm_intel\|kvm_amd'
.
Upvotes: 1
Reputation: 84569
You are making this more difficult than need be. You simply need to use a compound command to (1) check whether vmx
or svm
extensions are present in /proc/cpuinfo
, and (2) check whether the kvm
or kvm_intel
module is loaded by checking /proc/modules
. Using a compound command two calls are all that are needed:
#!/bin/bash
grep -wq 'vmx\|svm' /proc/cpuinfo || { ## check CPU support
printf "error: CPU does not support vmx or svm extensions.\n" >&2
exit 1
}
grep -q '^kvm' /proc/modules || { ## check modules loaded
printf "error: CPU supports KVM, but kvm modules not loaded.\n" >&2
exit 1
}
printf "CPU supports KVM and modules present.\n"
Example Use/Output
$ bash ~/scr/utl/kvmsupport.sh
CPU supports KVM and modules present.
You can do it any number of ways, but generally the simpler you can keep it, the less opportunity for error there is.
Upvotes: 1
Reputation: 58858
The standard way to get a zero exit code if and only if some pattern is matched is grep --quiet PATTERN
(or -q
if you don't have GNU Grep). You can use the same pattern in a pipeline if grep
is the last command in the pipeline or you use set -o pipefail
to get the first non-zero exit code in the pipeline as the exit code of the whole pipeline.
So in your case it would simply be:
if lsmod | awk '{print $1}' | grep -Eiw 'kvm\|kvm_intel\|kvm_amd'
then
…
Upvotes: 0