Comparing variables with strings bash

蓝咒 提交于 2020-01-03 02:08:06

问题


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.


回答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



回答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



回答3:


You are doing something wrong in your if-statement.

Simple answer:

  1. Make sure to use the == if you want to compare strings.
  2. Please use if [ "$version" == "xyz" ] instead of if [[ "$version" = "xyz" ]]

Summarized: if [ "$version"=="CentOS release 6.9 (Final)" ]; then and it sould work!

Regards, FrankTheTank



来源:https://stackoverflow.com/questions/46586267/comparing-variables-with-strings-bash

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!