如何在shell if语句中表示多个条件?

时间:2010-09-29 22:41:32

标签: bash shell unix

我想代表这样的多个条件:

if [ ( $g -eq 1 -a "$c" = "123" ) -o ( $g -eq 2 -a "$c" = "456" ) ]   
then  
    echo abc;  
else  
    echo efg;   
fi  

但是当我执行脚本时,它会显示

syntax error at line 15: `[' unexpected, 

第15行显示是否......

这种情况有什么问题?我想()会出现问题。

8 个答案:

答案 0 :(得分:333)

经典技术(转义元字符):

if [ \( "$g" -eq 1 -a "$c" = "123" \) -o \( "$g" -eq 2 -a "$c" = "456" \) ]
then echo abc
else echo efg
fi

我用双引号括起了对$g的引用;总的来说,这是一种很好的做法。严格来说,不需要括号,因为即使没有它们,-a-o的优先级也会正确。

请注意,-a-o运算符是test的POSIX规范的一部分,又称[,主要用于向后兼容性(因为它们是test的一部分例如,在第7版UNIX中{1}},但它们被POSIX明确标记为“过时”。 Bash(参见conditional expressions)似乎抢占了-a-o的经典和POSIX含义以及它自己的带参数的替代运算符。


小心谨慎,您可以使用更现代的[[运算符,但请注意Bash和Korn Shell中的版本(例如)不必相同。

for g in 1 2 3
do
    for c in 123 456 789
    do
        if [[ ( "$g" -eq 1 && "$c" = "123" ) || ( "$g" -eq 2 && "$c" = "456" ) ]]
        then echo "g = $g; c = $c; true"
        else echo "g = $g; c = $c; false"
        fi
    done
done

运行示例,在Mac OS X上使用Bash 3.2.57:

g = 1; c = 123; true
g = 1; c = 456; false
g = 1; c = 789; false
g = 2; c = 123; false
g = 2; c = 456; true
g = 2; c = 789; false
g = 3; c = 123; false
g = 3; c = 456; false
g = 3; c = 789; false

您不需要像[[那样引用[中的变量,因为它不是[的单独命令。


  

这不是一个经典问题吗?

我会这么认为的。但是,还有另一种选择,即:

if [ "$g" -eq 1 -a "$c" = "123" ] || [ "$g" -eq 2 -a "$c" = "456" ]
then echo abc
else echo efg
fi

事实上,如果您阅读了autoconf工具或相关软件包的“便携式外壳”指南,那么使用“||”和“&&”的这种表示法是他们推荐的。我想你甚至可以做到:

if [ "$g" -eq 1 ] && [ "$c" = "123" ]
then echo abc
elif [ "$g" -eq 2 ] && [ "$c" = "456" ]
then echo abc
else echo efg
fi

如果行动像回声一样微不足道,那也不错。当要重复的动作块是多行时,重复太痛苦了,并且最好使用其中一个早期版本 - 或者您需要将动作包装到在不同then块中调用的函数中。 p>

答案 1 :(得分:164)

在Bash中:

if [[ ( $g == 1 && $c == 123 ) || ( $g == 2 && $c == 456 ) ]]

答案 2 :(得分:25)

使用/bin/bash以下内容将起作用:

if [ "$option" = "Y" ] || [ "$option" = "y" ]; then
    echo "Entered $option"
fi

答案 3 :(得分:7)

$ g=3
$ c=133
$ ([ "$g$c" = "1123" ] || [ "$g$c" = "2456" ]) && echo "abc" || echo "efg"
efg
$ g=1
$ c=123
$ ([ "$g$c" = "1123" ] || [ "$g$c" = "2456" ]) && echo "abc" || echo "efg"
abc

答案 4 :(得分:7)

如果字符串变量中有空格并检查是否存在,请注意。一定要正确引用它们。

if [ ! "${somepath}" ] || [ ! "${otherstring}" ] || [ ! "${barstring}" ] ; then

答案 5 :(得分:1)

在bash中进行字符串比较时,可以使用以下技术。

if [ $var OP "val" ]; then
    echo "statements"
fi

示例:

var="something"
if [ $var != "otherthing" ] && [ $var != "everything" ] && [ $var != "allthings" ]; then
    echo "this will be printed"
else
    echo "this will not be printed"
fi

答案 6 :(得分:0)

#!/bin/bash

current_usage=$( df -h | grep 'gfsvg-gfslv' | awk {'print $5'} )
echo $current_usage
critical_usage=6%
warning_usage=3%

if [[ ${current_usage%?} -lt ${warning_usage%?} ]]; then
echo OK current usage is $current_usage
elif [[ ${current_usage%?} -ge ${warning_usage%?} ]] && [[ ${current_usage%?} -lt ${critical_usage%?} ]]; then
echo Warning $current_usage
else
echo Critical $current_usage
fi

答案 7 :(得分:0)

您也可以链接两个以上的条件:

if [ \( "$1" = '--usage' \) -o \( "$1" = '' \) -o \( "$1" = '--help' \) ]
then
   printf "\033[2J";printf "\033[0;0H"
   cat << EOF_PRINT_USAGE

   $0 - Purpose: upsert qto http json data to postgres db

   USAGE EXAMPLE:

   $0 -a foo -a bar



EOF_PRINT_USAGE
   exit 1
fi