将变量与字符串 bash 进行比较

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46586267/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 16:30:53  来源:igfitidea点击:

Comparing variables with strings bash

linuxbashif-statementstring-comparison

提问by Matthew

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.

我们很多CentOS服务器我想安装一些监控软件,软件是基于CentOS版本的,我想检查发布版本并根据它安装软件。

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.

似乎 if 语句成功运行而没有错误,而结果对于两个或所有三个 if 语句都不应该为真。我研究了 if 命令和测试,似乎我应该在 bash 中使用双括号和单个 = 符号。我相信我在做一些非常简单的错误,但我找不到它。

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.

得到一些回复后,我更改了代码,在等号 (=) 周围添加了空格。仍然没有按预期工作,因为比较应该在第二个 if 语句上返回 true 而不是。

Code #2

代码#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

结果#2

Different version detected than known:
CentOS Linux release 7.3.1611 (Core)
Aborted
false

Update

更新

declare -p versionlearned me that /etc/centos-releasehas 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.

declare -p version了解到我/etc/centos-release在脚本文件的末尾添加了一个空格,我相信在 CentOS 版本 6.9(最终版)上并非如此。在字符串中添加空格,或一起使用我的 known_version 变量并添加空格解决了问题,脚本现在按预期工作。

采纳答案by chepner

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.

您需要在=标志周围留出空白;如果没有它,shell 会将“表达式”视为单个单词,而不是比较两个单词是否相等。

[[ "$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.

[[ a=b ]]相当于[[ -n a=b ]],即,您只是在测试单个单词是否为非空字符串。

Whether you use =or ==inside [[ ... ]]is a matter of style; bashsupports both.

无论是使用=还是==内部[[ ... ]]都是风格问题;bash两者都支持。

I would avoid using a versionknownvariable altogether, and write the code like this:

我会versionknown完全避免使用变量,并编写如下代码:

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 casestatement

case声明

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

回答by Avihoo Mamka

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 ifstatements is that the result of your assignment expression is trueand therefore the ifstatement is being evaluated as trueand being executed.

您输入所有if语句的原因是您的赋值表达式的结果是true,因此该if语句被评估为true并正在执行。

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 [[ ]].

感谢@chepner 的评论,=当与单方括号[ ]或双方括号关联时,单个等号 ( ) 用于相等性检查[[ ]]。bash 还支持双等号 ( =) 在两种情况下作为相等性检查[ ][[ ]].

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

回答by FrankTheTank

You are doing something wrong in your if-statement.

您在 if 语句中做错了什么。

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" ]]
  1. ==如果要比较字符串,请确保使用。
  2. 请使用if [ "$version" == "xyz" ]代替if [[ "$version" = "xyz" ]]

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

总结:if [ "$version"=="CentOS release 6.9 (Final)" ]; then它行得通!

Regards, FrankTheTank

问候, FrankTheTank