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

我想像这样表示多个条件:

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 ....在哪里

这种情况有什么问题?我猜()有问题。

1070813 次浏览

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

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规范的一部分,主要是为了向后兼容(例如,因为它们是第7版UNIX中test的一部分),但它们被POSIX显式地标记为“过时”。Bash(参见条件表达式)似乎用自己的可选操作符抢占了-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工具或相关包的“便携式shell”指南,就会发现他们推荐使用“||”和“&&”这种符号。我想你甚至可以这样说:

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

在操作像回显一样琐碎的情况下,这还不错。当要重复的动作块是多行时,重复太痛苦了,最好使用早期版本——或者你需要将动作包装到在不同的then块中调用的函数中。

在Bash中:

if [[ ( $g == 1 && $c == 123 ) || ( $g == 2 && $c == 456 ) ]]
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"

输出:

美国广播公司

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

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

使用/bin/bash可以工作:

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

在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

你也可以链两个以上的条件:

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