首页 文章

Bash中的简单逻辑运算符

提问于
浏览
179

我有几个变量,我想检查以下条件(用文字写出,然后我尝试bash脚本失败):

if varA EQUALS 1 AND ( varB EQUALS "t1" OR varB EQUALS "t2" ) then 

do something

done.

在我失败的尝试中,我提出:

if (($varA == 1)) && ( (($varB == "t1")) || (($varC == "t2")) ); 
  then
    scale=0.05
  fi

5 回答

  • 1

    以下是if-then-else语句的简短版本的代码:

    ( [ $a -eq 1 ] || [ $b -eq 2 ] ) && echo "ok" || echo "nok"
    

    请注意以下事项:

    如果条件(即圆括号之间)是逻辑操作数(或/和),

    • ||&& 操作数在里面

    • ||&& 操作数如果条件意味着那么/ else

    实际上声明说:

    if(a = 1或b = 2)然后“ok”否则“nok”

  • 30
    if ([ $NUM1 == 1 ] || [ $NUM2 == 1 ]) && [ -z "$STR" ]
    then
        echo STR is empty but should have a value.
    fi
    
  • 520

    你写的东西实际上几乎可以工作(如果所有变量都是数字,它会起作用),但它根本不是惯用的方式 .

    • (…) 括号表示subshell . 's inside them isn' t表达式与许多其他语言类似 . 这是一个命令列表(就像外面的括号一样) . 这些命令在单独的子进程中执行,因此在括号内执行的任何重定向,赋值等都不会在括号外执行 .

    • 带有一个领先的美元符号, $(…)command substitution:括号内有一个命令,命令的输出用作命令行的一部分(在额外的扩展之后,除非替换在双引号之间,但那是another story) .

    • { … } 大括号就像是括号,因为它们对命令进行分组,但它们只会影响分析,而不会影响分组 . 程序 x=2; { x=4; }; echo $x 打印4,而 x=2; (x=4); echo $x 打印2.(大括号也需要它们周围的空格和一个分号才能关闭,而括号只需要一个语法怪癖 . )

    • 带有一个领先的美元符号, ${VAR}parameter expansion,扩展到变量的值,可能有额外的转换 .

    • ((…)) 双括号围绕arithmetic instruction,即整数计算,其语法类似于其他编程语言 . 此语法主要用于赋值和条件 .

    • 在算术表达式 $((…)) 中使用相同的语法,它扩展为表达式的整数值 .

    • [[ … ]] 双括号环绕conditional expressions . 条件表达式主要构建在operators上,例如 -n $variable ,用于测试变量是否为空,而 -e $file 用于测试文件是否存在 . 还有字符串相等运算符: "$string1" = "$string2" (请注意右侧是模式,例如 [[ $foo = a* ]] 测试 $foo 是否以 a 开始,而 [[ $foo = "a*" ]] 测试 $foo 是否完全 a* ),以及熟悉的 !&&|| 运算符用于否定,连接和分离以及用于分组的括号 . 请注意,每个运算符周围都需要一个空格(例如 [[ "$x" = "$y" ]] ,而不是[[“$ x”=“$ y”]]),括号内外的空格或字符如 ; (例如 [[ -n $foo ]] ,不是[[ -n $ foo]]) .

    • [ … ] 单括号是具有更多怪癖的条件表达式的替代形式(但更旧且更便携) . 不要写任何东西;当你找到包含它们的脚本时,开始担心它们 .

    这是用bash编写测试的惯用方法:

    if [[ $varA = 1 && ($varB = "t1" || $varC = "t2") ]]; then
    

    如果你需要可移植到其他shell,这将是方式(注意额外的引用和每个单独测试周围的单独括号集):

    if [ "$varA" = 1 ] && { [ "$varB" = "t1" ] || [ "$varC" = "t2" ]; }; then
    
  • 4

    很接近

    if [[ $varA -eq 1 ]] && [[ $varB == 't1' || $varC == 't2' ]]; 
      then 
        scale=0.05
      fi
    

    应该管用 .

    打破它

    [[ $varA -eq 1 ]]
    

    是一个整数比较,其中as

    $varB == 't1'
    

    是一个字符串比较 . 否则,我只是正确地对比分组 .

    双方括号分隔条件表达式 . 并且,我发现以下内容是关于这个主题的一个很好的阅读:["(IBM) Demystify test, [, [, ((, and if-then-else"

  • 0

    一个非常便携的版本(甚至是传统的bourne shell):

    if [ "$varA" = 1 -a \( "$varB" = "t1" -o "$varB" = "t2" \) ]
    then    do-something
    fi
    

    这具有最多只运行一个子进程的额外质量(即进程'['),无论shell风格如何 .

    如果变量包含数值,则将“=”替换为“-eq”,例如

    • 3 -eq 03是真的,但是

    • 3 = 03是假的 . (字符串比较)

相关问题