Bash如果具有多个条件的语句抛出错误


165

我正在尝试编写一个脚本,该脚本将检查两个错误标志,并且如果一个(或两个)标志被更改,它将回显-发生错误。我的剧本:

my_error_flag=0
my_error_flag_o=0
do something.....
if [[ "$my_error_flag"=="1" || "$my_error_flag_o"=="2" ] || [ "$my_error_flag"="1" &&     "$my_error_flag_o"="2" ]]; then
    echo "$my_error_flag"
else
    echo "no flag"
fi

基本上应该是这样:

if ((a=1 or b=2) or (a=1 and b=2))
  then
     display error
else
     no error
fi

我得到的错误是:

 line 26: conditional binary operator expected
 line 26: syntax error near `]'
 line 26: `if [[ "$my_error_flag"=="1" || "$my_error_flag_o"=="2" ] || [ "$my_error_flag"="1" && "$my_error_flag_o"="2" ]]; then'

我的括号搞砸了吗?



2
使用括号-()
AlikElzin-kilaka


3
从逻辑上讲,a==1 or b==2已经涵盖了的情况a==1 and b==2。在此单独进行测试是完全多余的。
Tripleee's

Answers:


247

使用-a(用于和)和-o(用于或)操作。

tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html

更新资料

其实你仍然可以使用&&,并||-eq操作。因此,您的脚本将如下所示:

my_error_flag=1
my_error_flag_o=1
if [ $my_error_flag -eq 1 ] ||  [ $my_error_flag_o -eq 2 ] || ([ $my_error_flag -eq 1 ] && [ $my_error_flag_o -eq 2 ]); then
      echo "$my_error_flag"
else
    echo "no flag"
fi

尽管就您而言,您可以舍弃最后两个表达式,而只使用一个或这样的操作:

my_error_flag=1
my_error_flag_o=1
if [ $my_error_flag -eq 1 ] ||  [ $my_error_flag_o -eq 2 ]; then
      echo "$my_error_flag"
else
    echo "no flag"
fi

3
@Simply_Me:否,如果逻辑或的两个操作数中的一个或两个为真,则该逻辑或为真。您正在考虑“异或”(XOR),如果恰好其操作数之一为true,则为true。(实际上,存在XOR的版本可处理2个以上的操作数,在这种情况下,如果奇数个操作数为true,则为true。)
Gordon Davisson

4
顺便说一句,原始代码中的问题包括使用[]进行分组(它们不这样做),以及未能在运算符周围放置空格(例如"$my_error_flag"="1"),这完全阻止了外壳将其识别为运算符。请阅读BashFAQ#17(关于分组)#31(关于不同类型的测试表达式之间的差异)。实际上,在这种情况下,使用算术表达式会更加容易。
Gordon Davisson

7
-a并被POSIX规范-o视为过时的; 使用单独的测试并与更新中的结合使用。||
chepner

1
无需使用子外壳进行分组,通常{}也可以使用进行分组。
phk

1
为了补充phk的上述评论,()正在bash中启动子外壳,该子外壳可能具有各种微妙的[可能不想要的]效果。
布雷特

70

您可以使用[[((关键字。当您使用[[的关键字,你必须使用字符串运算符,如-eq-lt。我认为,((最优选的运算,因为你可以直接使用运营商,如==<>

使用[[运算符

a=$1
b=$2
if [[ a -eq 1 || b -eq 2 ]] || [[ a -eq 3 && b -eq 4 ]]
then
     echo "Error"
else
     echo "No Error"
fi

使用((运算符

a=$1
b=$2
if (( a == 1 || b == 2 )) || (( a == 3 && b == 4 ))
then
     echo "Error"
else
     echo "No Error"
fi

不要使用-a-o操作员,因为它不是便携式的。


8

请尝试以下

if ([ $dateR -ge 234 ] && [ $dateR -lt 238 ]) || ([ $dateR -ge 834 ] && [ $dateR -lt 838 ]) || ([ $dateR -ge 1434 ] && [ $dateR -lt 1438 ]) || ([ $dateR -ge 2034 ] && [ $dateR -lt 2038 ]) ;
then
    echo "WORKING"
else
    echo "Out of range!"

2
( ... )创建子外壳-大量性能​​影响无济于事。
查尔斯·达菲

4
使用{ ...; }了无子shell创建分组。
查尔斯·达菲

1

您可以通过阅读MySQL的贡献者编写的entrypoint.sh 脚本来获得启发,该脚本检查是否设置了指定的变量。

如脚本所示,您可以使用来管道它们-a,例如:

if [ -z "$MYSQL_ROOT_PASSWORD" -a -z "$MYSQL_ALLOW_EMPTY_PASSWORD" -a -z "$MYSQL_RANDOM_ROOT_PASSWORD" ]; then
    ...
fi

1
-a在POSIX test标准的当前版本中标记为已过时;请参阅pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html上OB标记。使用有更可靠的代码。[ -z "$FOO" ] && [ -z "$BAR" ]
查尔斯·达菲
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.