如何在shell if语句中表示多个条件? [英] How to represent multiple conditions in a shell if statement?

查看:733
本文介绍了如何在shell if语句中表示多个条件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to represent multiple conditions like this:

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

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

but when I execute the script, it shows

syntax error at line 15: `[' unexpected, 

第15行是显示...的行.

where line 15 is the one showing if ....

这种情况怎么了?我想()有问题.

What is wrong with this condition? I guess something is wrong with the ().

推荐答案

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

Classic technique (escape metacharacters):

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

我已将对$g的引用括在双引号中;一般来说,这是一个好习惯.严格来说,不需要括号,因为-a-o的优先级使其正确,即使没有它们也是如此.

I've enclosed the references to $g in double quotes; that's good practice, in general. Strictly, the parentheses aren't needed because the precedence of -a and -o makes it correct even without them.

请注意,-a-o运算符是条件表达式)似乎先发制人-a-o的经典含义和POSIX含义,以及带有参数的自己的替代运算符.

Note that the -a and -o operators are part of the POSIX specification for test, aka [, mainly for backwards compatibility (since they were a part of test in 7th Edition UNIX, for example), but they are explicitly marked as 'obsolescent' by POSIX. Bash (see conditional expressions) seems to preempt the classic and POSIX meanings for -a and -o with its own alternative operators that take arguments.

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

With some care, you can use the more modern [[ operator, but be aware that the versions in Bash and Korn Shell (for example) need not be identical.

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运行示例:

Example run, using Bash 3.2.57 on Mac OS X:

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

您不需要像使用[一样在[[中引用变量,因为它不是与[相同的单独命令.

You don't need to quote the variables in [[ as you do with [ because it is not a separate command in the same way that [ is.

这不是经典问题吗?

Isn't it a classic question?

我会这么想的.但是,还有另一种选择,即:

I would have thought so. However, there is another alternative, namely:

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

实际上,如果您阅读了autoconf工具或相关软件包的便携式外壳"指南,则建议使用这种表示法-使用'||'和'&&'.我想您甚至可以走得更远:

Indeed, if you read the 'portable shell' guidelines for the autoconf tool or related packages, this notation — using '||' and '&&' — is what they recommend. I suppose you could even go so far as:

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

在动作与回声一样微不足道的地方,这还不错.如果要重复的操作块为多行,则重复会很痛苦,并且较早的版本是可取的-否则您需要将操作包装到在不同的then块中调用的函数中.

Where the actions are as trivial as echoing, this isn't bad. When the action block to be repeated is multiple lines, the repetition is too painful and one of the earlier versions is preferable — or you need to wrap the actions into a function that is invoked in the different then blocks.

这篇关于如何在shell if语句中表示多个条件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆