bash 如何在shell if语句中表示多个条件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3826425/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to represent multiple conditions in a shell if statement?
提问by user389955
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 ()
.
这种情况有什么问题?我猜()
.
回答by Jonathan Leffler
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; 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.
我已经$g
用双引号把对的引用括起来了;总的来说,这是一种很好的做法。严格来说,不需要括号,因为即使没有它们,-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. Bash (see conditional expressions) seems to preempt the classic and POSIX meanings for -a
and -o
with its own alternative operators that take arguments.
请注意,-a
和-o
运算符是 POSIX 规范的一部分test
,也就是[
,主要是为了向后兼容(例如,因为它们是test
第 7 版 UNIX的一部分),但它们被 POSIX 明确标记为“过时”。Bash(请参阅条件表达式)似乎抢占了经典和 POSIX 含义,-a
并-o
使用其自己的带参数的替代运算符。
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 '||
' and '&&
' — is what they recommend. I suppose you could even go so far as:
实际上,如果您阅读了该autoconf
工具或相关软件包的“便携式外壳”指南,那么他们推荐使用这种符号(使用“ ||
”和“ &&
”)。我想你甚至可以做到:
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
块中调用。
回答by Paused until further notice.
In Bash:
在 Bash 中:
if [[ ( $g == 1 && $c == 123 ) || ( $g == 2 && $c == 456 ) ]]
回答by sunitha
Using /bin/bash
the following will work:
使用/bin/bash
以下将起作用:
if [ "$option" = "Y" ] || [ "$option" = "y" ]; then
echo "Entered $option"
fi
回答by orkoden
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
回答by ghostdog74
$ 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
回答by Ashan Priyadarshana
In bash for string comparison, you can use the following technique.
在用于字符串比较的 bash 中,您可以使用以下技术。
if [ $var OP "val" ]; then
echo "statements"
fi
Example:
例子:
var="something"
if [ $var != "otherthing" ] && [ $var != "everything" ] && [ $var != "allthings" ]; then
echo "this will be printed"
else
echo "this will not be printed"
fi
回答by Yordan Georgiev
you can chain more than 2 conditions too :
您也可以链接两个以上的条件:
if [ \( "" = '--usage' \) -o \( "" = '' \) -o \( "" = '--help' \) ]
then
printf "3[2J";printf "3[0;0H"
cat << EOF_PRINT_USAGE
#!/bin/bash
current_usage=$( df -h | grep 'gfsvg-gfslv' | awk {'print '} )
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
- Purpose: upsert qto http json data to postgres db
USAGE EXAMPLE:
##代码## -a foo -a bar
EOF_PRINT_USAGE
exit 1
fi