关于if语句:如何在Bash中用boolean写if / else?

How to write if/else with boolean in Bash?

本问题已经有最佳答案,请猛点这里访问。

如何编写if-then语句来在这些变量之间切换,例如:

1
2
3
4
5
6
7
8
9
if(switch){
  server_var_shortname=$server_shared_shortname
  server_var=$server_shared
  server_var_bare=$server_shared_bare
} else {
  server_var_shortname=$server_vps_shortname
  server_var=$server_vps
  server_var_bare=$server_vps_bare
}

我不熟悉bash语法,基本上只需要一个关于布尔值的if/else语句。我也可以使用真/假值吗?另外,我该如何做else语句?

1
2
3
4
5
6
7
$switch=true;
if $switch
then
  server_var_shortname=$server_shared_shortname
  server_var=$server_shared
  server_var_bare=$server_shared_bare
fi


首先,shell(包括bash)没有布尔值;它们甚至没有整数(尽管它们可能有点假)。大多数情况下,它们都有弦。bash也有数组…弦乐的假扮布尔人有很多种方法;我最喜欢的是使用字符串"真"和"假"。这些命令的名称也恰好是总是成功和失败的命令的名称,因为if语句实际上接受了一个命令,如果成功则运行then子句,如果失败则运行else子句,这两个名称非常有用。因此,您可以"运行"布尔值,如果设置为"真",它将成功;如果设置为"假",它将失败。这样地:

1
2
3
4
5
6
7
8
9
10
11
switch=true  # This doesn't have quotes around it, but it's a string anyway.
# ...
if $switch; then
    server_var_shortname=$server_shared_shortname
    server_var=$server_shared
    server_var_bare=$server_shared_bare
else
    server_var_shortname=$server_vps_shortname
    server_var=$server_vps
    server_var_bare=$server_vps_bare
fi

请注意,对于if您将看到的更常见的格式有方括号,如if [ something ]; then。在这种情况下,[实际上是一个命令(不是某种有趣的分组运算符),它将其参数评估为表达式;因此,["some string" ="some other string" ]是一个将失败的命令,因为字符串不相等。你可以使用if ["$switch" = true ]; then,但我更喜欢作弊,直接使用假布尔值。

警告:如果你确实使用了我建议的欺骗,请确保你的"布尔"变量设置为"真"或"假"——不是未设置,也不是设置为其他值。如果设置为其他任何内容,我对结果不承担任何责任。

其他一些语法注释:

  • 获取变量值时,而不是分配给变量时,对变量使用$。你在上面有一个$switch=true;,这会给你带来一个错误。
  • 另外,在这行末尾还有一个分号。这是不必要的;分号用于分隔同一行(以及其他一些位置)上的多个命令,但不需要结束一行上的最后一个(/only)命令。
  • [命令(也称为test)的语法有点奇怪。主要是因为它是一个命令,所以它通过常规的命令解析,例如,[ 5 > 19 ]被解析为[ 5 ],输出被发送到一个名为"19"的文件(然后是真的,因为"5"是非空的)。[ 5">" 19 ]比较好,但仍然计算为真,因为>进行字符串(字母)比较,"5"在"19"之后按字母顺序排列。[ 5 -gt 19 ]做了预期的事情。

    还有[[ ]](( ))(用于数学,而不是字符串;也不是所有shell)。参见bashfaq 31。

  • 将命令放入变量通常是一个坏主意。参见bashfaq 50。
  • shellcheck.net是你的朋友。

这是一个很好的指导,为If else。但我想展示一种不同的方法(您也可以在第3页的链接中找到)。

您的代码看起来像javascript,所以我认为对于switch,您还可以使用case命令而不是if。javascript中的switch与shell中的case类似,但没有检查布尔值的方法。您可以检查字符串值,如etruefalse,还可以检查数字。

例子。。。

1
2
3
4
5
6
7
8
9
#!/bin/bash
case"$Variable" in
false|0|"")
    echo"Boolean is set to false."
;;
*)
    echo"Boolean is set to true."
;;
esac

加法

记住,有许多程序和工具以不同的形式使用boolean values

两实例…SQL通常使用数字作为布尔值。javascript使用真值和假值。

意思:在处理布尔值之前,您的bash脚本必须知道布尔值的格式!


bash没有布尔值的概念-没有真/假值。建构

1
[ $switch ]

将为真,除非未设置switch变量或将其设置为空字符串。

1
2
3
4
5
[ ]    && echo yes                      # nothing is echoed
["" ] && echo yes                      # nothing is echoed
unset switch && [ $switch ] && echo yes # nothing is echoed
switch=1 && [ $switch ] && echo yes     # yes is echoed
switch=0 && [ $switch ] && echo yes     # yes is echoed - shell makes no distinction of contents - it is true as long it is not empty

参见:

  • 如何在shell脚本中声明和使用布尔变量?


除了@gordon出色的答案,在bash中,您还可以使用双括号结构。适用于整数,它是最接近其他语言的形式。演示:

1
2
3
4
5
6
7
8
9
10
11
for i in {-2..2}; do
    printf"for %s""$i"

    if (( i ))   # you can omit the `$`
    then
        echo is nonzero
    else
        echo is zero
    fi

done

输出:

1
2
3
4
5
for -2 is nonzero
for -1 is nonzero
for 0 is zero
for 1 is nonzero
for 2 is nonzero

您可以在内部使用任何算术运算,例如:

1
2
3
4
5
6
7
8
9
10
for i in {1..6}; do
    printf"for %s""$i"

    if (( i % 2 )) #modulo
    then
        echo odd
    else
        echo even
    fi
done

输出

1
2
3
4
5
6
for 1 odd
for 2 even
for 3 odd
for 4 even
for 5 odd
for 6 even

你需要的是这样的东西:

1
2
3
4
5
6
7
8
9
10
11
if
  CONDITION_SEE_BELOW
then
  server_var_shortname=$server_shared_shortname
  server_var=$server_shared
  server_var_bare=$server_shared_bare
else
  server_var_shortname=$server_vps_shortname
  server_var=$server_vps
  server_var_bare=$server_vps_bare
fi

在bash(和其他shell)中,CONDITION_SEE_BELOW部分必须是一个命令。命令返回一个数值,按照惯例,0表示"真",任何非零值表示"假"。如果命令在所有其他情况下返回0else子句,则执行then子句。返回值不是命令输出的文本。在shell中,可以在执行命令后立即使用特殊变量expansion $?访问它。

您可以使用命令truefalse来测试这一点,它们只做一件事:生成零(true和非零(false返回值。在命令行中尝试此操作:

1
2
true ; echo"true returns $?"
false ; echo"false returns $?"

在条件中可以使用任何命令。有两个特别的命令是根据定义条件的思想创建的:经典的测试命令[ ](实际的命令只是开括号,也可用作test命令),和双括号的、特定于bash的[[ ]](技术上不是命令,而是命令特殊shell语法)。

例如,假设您的switch变量不包含任何内容(空字符串)或某些内容(至少包含一个字符的字符串),并假定在您的情况下,空字符串是"false",任何其他字符串是"true"。然后你可以用它作为一个条件:

1
["$switch" ]

如果只包含空格和制表符的字符串被认为是空的(这是标准shell扩展和命令参数分词的结果),则可以删除双引号。

双括号测试命令基本上是相似的,但有一些好处,包括大多数时候不需要双引号,在表达式中支持带&&||的布尔逻辑,并具有正则表达式匹配功能。然而,这是一种羞怯。

您可以将其用作可以使用两个测试命令执行的各种测试的引用:

https://www.gnu.org/software/bash/manual/bashref.html bash条件表达式

如果对shell编程感兴趣,一定要了解您可以使用的各种测试,因为您可能经常使用其中的许多测试。