如何测试字符串和整数相等,并与逻辑 && 和 || 结合bash 中的运算符?

问题描述 投票:0回答:5

我有几个变量,我想检查以下条件(用文字写出来,然后是我在 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
bash logical-operators
5个回答
848
投票

你所写的实际上几乎可以工作(如果所有变量都是数字,它就会工作),但这根本不是一种惯用的方式。

  • (…)
    括号表示subshell。它们的内部内容与许多其他语言中的表达方式不同。它是一个命令列表(就像括号外一样)。这些命令在单独的子进程中执行,因此在括号内执行的任何重定向、赋值等在括号外都不起作用。
    • 以美元符号开头,
      $(…)
      命令替换:括号内有一个命令,该命令的输出用作命令行的一部分(在额外扩展之后,除非替换是在双引号之间,但那是另一个故事)。
  • { … }
    大括号就像括号一样,它们对命令进行分组,但它们只影响解析,而不影响分组。程序
    x=2; { x=4; }; echo $x
    打印 4,而
    x=2; (x=4); echo $x
    打印 2。(大括号还需要在其周围有空格,并且在结束之前需要分号,而括号则不需要。这只是一个语法怪癖。)
    • 带有前导美元符号,
      ${VAR}
      是一个参数扩展,扩展为变量的值,并可能进行额外的转换。
  • ((…))
    双括号包围着一个算术指令,即整数计算,其语法类似于其他编程语言。此语法主要用于赋值和条件语句。
    • 算术表达式
      $((…))
      使用相同的语法,它扩展为表达式的整数值。
  • [[ … ]]
    双括号包围条件表达式。条件表达式主要构建在 运算符 上,例如
    -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

(请注意每个单独测试周围的额外引用和单独的括号组,以及使用传统的

=
运算符而不是 ksh/bash/zsh
==
变体)


46
投票

非常接近。

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

应该可以。

分解它,

[[ $varA -eq 1 ]]

是整数比较, 而

$varB == 't1'

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

双方括号界定条件表达式。而且,我发现以下内容是关于该主题的好读物:“(IBM)揭秘测试,[,[[,((和 if-then-else”


12
投票

一个非常便携的版本(甚至对于旧版Bourne shell):

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

这具有最多仅运行一个子进程(即进程

[
)的额外质量,无论 shell 风格如何。

如果变量包含数值,则将

=
替换为
-eq
,例如

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

9
投票

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

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

注意以下事项:

  1. if

    条件内(即圆括号之间)的

    ||
    &&操作数是逻辑操作数(或/和)

  2. ||
    &&
    位于 if 条件之外的操作数表示 then/else

实际上,声明说:

if (a=1 或 b=2) then "ok" else "nok"


-1
投票
if ([ $NUM1 == 1 ] || [ $NUM2 == 1 ]) && [ -z "$STR" ]
then
    echo STR is empty but should have a value.
fi
© www.soinside.com 2019 - 2024. All rights reserved.