Comparing variables with strings bash
Solution 1
You need whitespace around the =
sign; without it, the shell treats the "expression" as a single word, not a comparison of two words for equality.
[[ "$version" = "CentOS release 6.9 (Final)" ]]
[[ a=b ]]
is equivalent to [[ -n a=b ]]
, i.e., you are simply testing if the single word is a non-empty string.
Whether you use =
or ==
inside [[ ... ]]
is a matter of style; bash
supports both.
I would avoid using a versionknown
variable altogether, and write the code like this:
version=$(</etc/centos-release)
known_version1="CentOS release 6.9 (Final)"
known_version2="CentOS Linux release 7.3.1611 (Core)"
if [[ "$version" = "$known_version1" ]] ; then
echo "Same versions as expected"
#run commands for this specific version
elif [[ "$version" = "$known_version2" ]] ; then
echo "Same versions as expected v2"
#run commands for this specific version
else
echo "Different version detected than known:"
echo "$version"
echo "Aborted"
fi
or a case
statement
case $version in
"$known_version1")
echo "Same versions as expected"
# ...
;;
"$known_version2")
echo "Same versions as expected v2"
# ...
;;
*)
echo "Different version detected than known:"
echo "$version"
echo "Aborted"
esac
Solution 2
As a general rule of thumb, on probably all of the programming languages, a single equal (=
) sign is for assignment and not for equality check which in this case is double equal (=
) sign.
The reason you're entering all of your if
statements is that the result of your assignment expression is true
and therefore the if
statement is being evaluated as true
and being executed.
Update
Thanks for @chepner's comment, a single equal (=
) sign is used for equality check when associated with single square brackets [ ]
or double square brackets [[ ]]
. bash also supports double equal (=
) sign as equality check in both cases [ ]
or [[ ]]
.
What you want is probably this:
#!/bin/bash
versionknown=false
version=$(</etc/centos-release)
known_version1="CentOS release 6.9 (Final)"
known_version2="CentOS Linux release 7.3.1611 (Core)"
if [[ "$version" == "CentOS release 6.9 (Final)" ]] ; then
echo "Same versions as expected"
versionknown=true
#run commands for this specific version
fi
if [[ "$version" == "CentOS Linux release 7.3.1611 (Core)" ]] ; then
echo "Same versions as expected v2"
versionknown=true
#run commands for this specific version
fi
if [[ "$versionknown" == "false" ]] ; then
echo "Different version detected than known:"
echo $version
echo "Aborted"
fi
echo $versionknown
Related videos on Youtube
Matthew
Updated on June 04, 2022Comments
-
Matthew almost 2 years
Context
For quite a lot of our CentOS servers I would like to install some monitoring software, the software is based on the CentOS version, I want to check the release version and install software based on that.
Issue
It seems that the if statements are run successfully without errors while the results never should be true for both or all three if statements. I've looked into the if commands and the tests, it seems that I should use double brackets and single = symbol in bash. I believe that I'm doing something really simple wrong, but I just can't find it.
Code
#!/bin/bash versionknown=false version=$(</etc/centos-release) known_version1="CentOS release 6.9 (Final)" known_version2="CentOS Linux release 7.3.1611 (Core)" if [[ "$version"="CentOS release 6.9 (Final)" ]] ; then echo "Same versions as expected" versionknown=true #run commands for this specific version fi if [[ "$version"="CentOS Linux release 7.3.1611 (Core)" ]] ; then echo "Same versions as expected v2" versionknown=true #run commands for this specific version fi if [[ "$versionknown"=false ]] ; then echo "Different version detected than known:" echo $version echo "Aborted" fi echo $versionknown
Results
Same versions as expected Same versions as expected v2 Different version detected than known: CentOS Linux release 7.3.1611 (Core) Aborted true
Update
After getting some responses I've changed my code, adding spaces around the equal signs(=). Still doesn't work as intended since the comparison should return true on the second if statement which it doesn't.
Code #2
#!/bin/bash versionknown=false version=$(</etc/centos-release) known_version1="CentOS release 6.9 (Final)" known_version2="CentOS Linux release 7.3.1611 (Core)" if [[ "$version" = "CentOS release 6.9 (Final)" ]] ; then echo "Same versions as expected" versionknown=true #run script for this specific version fi if [[ "$version" = "CentOS Linux release 7.3.1611 (Core)" ]] ; then echo "Same versions as expected v2" versionknown=true #run script for this specific version fi if [[ "$versionknown" = false ]] ; then echo "Different version detected than known:" echo $version echo "Aborted" fi echo $versionknown
Results #2
Different version detected than known: CentOS Linux release 7.3.1611 (Core) Aborted false
Update
declare -p version
learned me that/etc/centos-release
has a space added to the end of the script file, I believe that on CentOS release 6.9 (Final) that wasn't the case. Adding the space in the string, or all together making use of my known_version variables and adding the space solves the issues, script now works as intended. -
chepner over 6 years
=
is the string equality operator with[
;==
is supported bybash
but not other shells. If you feel the need to use==
, use the[[
command instead. -
chepner over 6 yearsThe general rule of thumb does not apply to
[
, where=
is the equality operator.==
is an (unnecessary) extension inbash
. -
Matthew over 6 yearsI've changed the script, it now gives the same outcome without the first two lines(as stated in the post), which still is strange since $version is equal to 'CentOS Linux release 7.3.1611 (Core)' and thus should result to the second if statement and not the first or the last. Any ideas?
-
chepner over 6 yearsWhat is the output if you replace
echo $version
withdeclare -p version
? -
Matthew over 6 yearsThis was it, with the declare I got
declare -- version="CentOS Linux release 7.3.1611 (Core) "
which has an extra space. Thus the if statement is false because the string is without the space, after changing the string in the second statement and adding a space it works as intended, thanks!