如何在shell中声明多个条件?

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

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行是显示如果….

这种情况怎么了? 我猜()有些问题。

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

 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操作符是POSIX test规范的一部分,又名[主要是为了向后兼容(例如,因为它们是第7版UNIX中的test的一部分),但是它们明确标记为“过时'通过POSIX。 Bash(参见条件expression式 )似乎用自己的替代运算符抢占了-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 

你不需要在[[就像你这样做[因为它不是一个单独的命令,就像[是]一样)引用variables。


这不是一个典型的问题吗?

我会这样想的。 不过,还有另外一个select,即:

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

事实上,如果您阅读autoconf工具或相关软件包的“便携式shell”准则,则使用“ || '和' && '是他们推荐的。 我想你甚至可以走得这么远:

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

如果这些行动像回声一样微不足道,这并不坏。 当要重复的动作块是多行时,重复过于痛苦,并且早期版本之一更可取 – 或者需要将动作封装到在不同的块中调用的函数中。

在Bash:

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

使用/bin/bash以下将工作:

 if [ "$option" = "Y" ] || [ "$option" = "y" ]; then echo "Entered $option" fi 
 $ 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 

如果在stringvariables中有空格并且检查是否存在,请小心。 一定要引用他们。

 if [ ! "${somepath}" ] || [ ! "${otherstring}" ] || [ ! "${barstring}" ] ; then 
 #!/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