本文翻译自:How to represent multiple conditions in a shell if statement?
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,
where line 15 is the one showing if .... 第15行显示的是....
What is wrong with this condition? 这种情况怎么了? I guess something is wrong with the ()
. 我猜想()
。
#1楼
参考:https://stackoom.com/question/g3qx/如何在if语句中表示多个条件
#2楼
Be careful if you have spaces in your string variables and you check for existence. 如果字符串变量中有空格并检查是否存在,请格外小心。 Be sure to quote them properly. 确保正确引用它们。
if [ ! "${somepath}" ] || [ ! "${otherstring}" ] || [ ! "${barstring}" ] ; then
#3楼
Using /bin/bash
the following will work: 使用/bin/bash
可以正常工作:
if [ "$option" = "Y" ] || [ "$option" = "y" ]; then
echo "Entered $option"
fi
#4楼
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
I've enclosed the references to $g
in double quotes; 我已将对$g
的引用括在双引号中; 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
的优先级使得即使没有它们也正确。
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. 请注意, -a
和-o
运营商的POSIX规范的一部分test
,又名[
,主要用于向后兼容性(因为他们的部分test
在第7版UNIX等),但它们被明确标记为“过时由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(请参阅条件表达式 )似乎以其自己的带参数的替代运算符抢占了-a
和-o
的经典含义和POSIX含义。
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. 一定要小心,您可以使用更现代的[[
运算符,但是请注意,例如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
Example run, using Bash 3.2.57 on Mac OS X: 在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
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
Indeed, if you read the 'portable shell' guidelines for the autoconf
tool or related packages, this notation — using ' ||
确实,如果您阅读了autoconf
工具或相关软件包的“便携式外壳”指南,则使用- ||
表示。 ' 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
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. 当要重复执行的动作块为多行时,重复会很痛苦,并且较早的版本之一是可取的-否则您需要将动作包装到在不同的then
块中调用的函数中。
#5楼
在Bash中:
if [[ ( $g == 1 && $c == 123 ) || ( $g == 2 && $c == 456 ) ]]
#6楼
$ 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