【问题标题】:Bash if statement with multiple conditions throws an error具有多个条件的 Bash if 语句会引发错误
【发布时间】:2013-04-18 15:49:17
【问题描述】:

我正在尝试编写一个脚本来检查两个错误标志,如果一个标志(或两个)被更改,它会回显——发生错误。我的脚本:

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'

我的括号弄乱了吗?

【问题讨论】:

标签: bash if-statement flags


【解决方案1】:

请尝试关注

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!"

【讨论】:

  • ( ... ) 创建子外壳 -- 对性能有很多影响而没有任何好处。
  • 使用{ ...; } 进行分组而不创建子shell。
【解决方案2】:

您可以通过阅读由 MySQL 的贡献者编写的 entrypoint.sh script 来获得一些灵感,该文件检查是否设置了指定的变量。

如脚本所示,您可以使用-a 对它们进行管道传输,例如:

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

【讨论】:

【解决方案3】:

使用-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

【讨论】:

  • @Simply_Me:不,如果其中一个 或两个 操作数为真,则逻辑 OR 为真。您正在考虑“异或”(XOR),如果其中一个操作数为真,则为真。 (实际上,有些版本的 XOR 可以处理超过 2 个操作数,在这种情况下,如果奇数个操作数为真,则为真。)
  • 顺便说一句,原始代码中的问题包括使用[] 进行分组(他们不这样做),以及未能在运算符周围放置空格(例如"$my_error_flag"="1"),这可以防止外壳将其识别为操作员。请阅读BashFAQ #17 (on grouping)#31 (on the difference between different types of test expression)。实际上,在这种情况下,使用arithmetic expression 会更容易。
  • -a-oPOSIX specification 认为已过时;使用单独的测试与 || 在更新中结合。
  • 不需要使用子shell进行分组,通常使用{}进行分组也是可以的。
  • 添加到上面 phk 的评论中,( ) 正在 bash 中启动子shell,这可能会产生各种微妙的 [可能不需要的] 效果。
【解决方案4】:

您可以使用[[(( 关键字。使用[[关键字时,必须使用-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 运算符,因为它不是便携式的。

【讨论】:

    猜你喜欢
    • 2014-10-20
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2016-12-13
    • 2019-10-20
    • 1970-01-01
    相关资源
    最近更新 更多