【问题标题】:How can I write if/else with Boolean in Bash? [duplicate]如何在 Bash 中使用布尔值编写 if/else? [复制]
【发布时间】:2017-08-26 10:33:11
【问题描述】:

如何编写一个“if then”语句在这些变量之间切换,如下所示?

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'语句?

$switch=true;
if $switch
then
  server_var_shortname=$server_shared_shortname
  server_var=$server_shared
  server_var_bare=$server_shared_bare
fi

【问题讨论】:

  • 我选择的副本涵盖了这个问题的“布尔”方面,没有讨论ifthenelifelse、@ 的更基本但也很重要的机制987654327@ 在 Bash 和其他类似 POSIX 的 shell 中。问题中的表示法更像 C——C shell 更直接地支持该表示法,但您可能不应该使用 C shell,尤其是不用于严肃的脚本工作(搜索“csh 编程被认为有害”以解释原因;海贝壳应该留在海边)。

标签: bash if-statement boolean


【解决方案1】:

除了Gordon's excellent answer,在Bash 中你也可以使用double-parentheses construct。它适用于整数,它是最接近其他语言的形式。演示:

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

输出:

for -2 is nonzero
for -1 is nonzero
for 0 is zero
for 1 is nonzero
for 2 is nonzero

你可以在里面使用任何算术运算,例如:

for i in {1..6}; do
    printf "for %s " "$i"

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

输出

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

【讨论】:

    【解决方案2】:

    你需要这样的东西:

    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 表示“真”,任何非零值都表示“假”。如果命令返回0,则将执行then 子句,或者在所有其他情况下返回else 子句。返回值是不是命令输出的文本。在 shell 中,您可以在执行命令后立即使用特殊变量扩展 $? 访问它。

    您可以使用命令truefalse 对其进行测试,它们会做一件事:生成零(true)和非零(false)返回值。在命令行试试这个:

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

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

    例如,假设您的 switch 变量不包含任何内容(空字符串)或某些内容(至少包含一个字符的字符串),并假设在您的情况下您的意思是空字符串是“假”和任何其他字符串是真实的”。然后你可以用作条件:

    [ "$switch" ]
    

    如果您可以将仅包含空格和制表符的字符串视为空字符串(这将作为标准 shell 扩展和命令参数分词的结果而发生),那么您可以删除双引号。

    双括号测试命令大体相似,但有一些优点,包括大部分时间不需要双引号,支持在表达式中使用 &&|| 的布尔逻辑,以及正则表达式匹配作为一个特征。然而,它是一种巴什主义。

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

    6.4 Bash Conditional Expressions

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

    【讨论】:

      【解决方案3】:

      Here is a good guide for If else。但我想展示一种不同的方法(您也可以在第 3 页的链接中找到)。

      您的编码看起来像 JavaScript,所以我认为 Switch 您也可以表示 case 命令而不是 if。 JavaScript 中的Switch 类似于shell 中的case,但没有任何方法可以检查布尔值。您可以检查truefalse 之类的字符串值,也可以检查数字。

      示例...

      #!/bin/bash
      case "$Variable" in
      false|0|"")
          echo "Boolean is set to false."
      ;;
      *)
          echo "Boolean is set to true."
      ;;
      esac
      

      加法

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

      两个例子...
      SQL 通常使用数字作为布尔值。
      JavaScript 使用 true 和 false 值。

      意思:你的 Bash 脚本在处​​理布尔值之前必须知道它们的格式!

      【讨论】:

        【解决方案4】:

        首先,shell(包括 Bash)没有布尔值;他们甚至没有整数(尽管他们可以伪造它)。大多数情况下,它们都有字符串。

        Bash 也有数组......字符串。有多种伪造布尔值的方法;我最喜欢的是使用字符串“true”和“false”。这些也恰好分别是总是成功和失败的命令的名称,这很方便,因为if 语句实际上接受一个命令,如果成功则运行then 子句,如果成功则运行else 子句失败。因此,您可以“运行”布尔值,如果设置为“true”,它将成功,如果设置为“false”,它将失败。像这样:

        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;,这会给你一个错误。
        • 此外,您在该行的末尾有一个分号。这是不必要的;分号用于分隔同一行(以及其他几个地方)上的多个命令,但不需要它们来结束一行中的最后一个(/唯一)命令。
        • [ 命令(也称为test)有一种奇怪的语法。主要是因为它是一个命令,所以它通过通常的命令解析,例如[ 5 > 19 ] 被解析为 [ 5 ] 并将输出发送到名为“19”的文件(然后为真,因为“5”是非空白的)。 [ 5 ">" 19 ] 更好,但仍然评估为 true,因为 > 进行字符串(按字母顺序)比较,并且“5”按字母顺序排在“19”之后。 [ 5 -gt 19 ] 做了预期的事情。

          还有[[ ]](类似,但语法更简洁,并非在所有shell中都可用)和(( ))(用于数学,不是字符串;也不是在所有shell中)。见Bash FAQ #31

        • 将命令放在变量中通常是个坏主意。见Bash FAQ #50

        • shellcheck.net 是你的朋友。

        【讨论】:

          【解决方案5】:

          Bash 没有任何布尔概念——没有真/假值。构造

          [ $switch ]
          

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

          [ ]    && 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 - the shell makes no distinction of contents - it is true as long it is not empty
          

          另见:

          【讨论】:

          • 很棒的测试!!
          猜你喜欢
          • 2021-08-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-18
          • 2014-12-19
          • 2011-04-18
          • 2021-05-04
          相关资源
          最近更新 更多