Bash中的简单逻辑运算符

时间:2011-06-07 19:18:06

标签: bash logical-operators

我有几个变量,我想检查以下条件(用文字写出,然后我尝试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 个答案:

答案 0 :(得分:576)

你所写的内容实际上几乎可行(如果所有变量都是数字,它会起作用),但它根本不是惯用的方法。

  • (…)括号表示subshell。它们里面的内容不像许多其他语言中那样。这是一个命令列表(就像外面的括号一样)。这些命令在单独的子进程中执行,因此在括号内执行的任何重定向,赋值等都不会在括号外执行。
    • 使用前导美元符号,$(…)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

答案 1 :(得分:31)

非常接近

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

应该有用。

分解

[[ $varA -eq 1 ]] 

是整数比较 在哪里

$varB == 't1'

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

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

答案 2 :(得分:6)

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

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

除了shell的味道之外,它还具有最多只运行一个子进程的额外质量(即进程'[')。

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

  • 3 -eq 03是真的,但是
  • 3 = 03是假的。 (字符串比较)

答案 3 :(得分:1)

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

CREATE OR REPLACE PROCEDURE stu_proc(
        col_st_id IN student_main.id%type,
        st_cur OUT sys_refcursor)
    IS  
    BEGIN
      OPEN st_cur for 
       SELECT sm.*
        FROM student_main sm
        JOIN student_details sd
        ON sm.id    = sd.st_id
        WHERE sm.id = col_st_id;

      EXCEPTION
      WHEN no_data_found THEN
        dbms_output.put_line('Student details not found');
    END;

请注意以下事项:

    如果条件(即圆括号之间)是逻辑操作数(或/和),则
  1. ( [ $a -eq 1 ] || [ $b -eq 2 ] ) && echo "ok" || echo "nok" ||个操作数

  2. &&||操作数,如果条件意味着/那么

  3. 实际上声明说:

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

答案 4 :(得分:0)

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