Bash shell 流程控制——条件控制

条件控制语句

基本语法:

1
2
3
4
if command  # 该命令退出状态码为0时为真
then
commands
fi

或者也可以:

1
2
3
if command; then
commands
fi

else的格式:

1
2
3
4
5
6
if command
then
commands
else
commands
fi

elif的格式:

1
2
3
4
5
6
7
if command
then
commands
elif command
then
commands
fi

可以执行多个elif,同时,最后一个elif后面可以继续接else,从而达到复杂的条件分支执行效果。

与其他编程语言不同的是,Bash Shellif后面跟的是一个命令,当执行到该行的时候,如果命令执行后退出状态码为0,则会认为是TRUE,继而执行then后面的命令,否则,即退出状态码非零,将认为是FALSEthen后面的命令将不被执行。在终端中可以执行一个命令后,紧接着执行echo $?便可以显示上一个命令的退出状态码了。

test命令

Bash Shell提供了if条件控制,但是条件只能是一个命令,根据其退出状态码决定真假,这使得用起来收到了很大限制。test提供了测试不同条件的途径,准确说还是上述if的用法,只不过test命令可以对其测试的条件进行判断,根据条件的真假适当返回执行后的退出状态码,从而达到根据条件执行分支的效果。test命令的格式为:

1
test condition

condition即为test命令测试的条件,条件为真,则test返回退出状态码为0,否则为非零。因此,if条件控制的写法可以写成(其他类似):

1
2
3
if test condition; then
commands
fi

此外,Bash提供了另外一种方便的写法,上述格式等效于:

1
2
3
if [ condition ]; then # 注意方括号两边内侧的空格
commands
fi

至于condition可以写啥,可以执行man test命令查看命令手册,上面有较为详细的说明,下面对各种情况下的条件进行总结。

test命令条件格式

数值比较

数据比较的操作有如下表格中的几操作:

符号 描述
-eq equal等于
-ge greater equal大于等于
-gt greater than大于
-le less equal小于等于
-lt less than小于
-ne not equal不等于

上述符号的使用格式为:

1
[ int1 -xx int2 ]

表示整数int1和整数int2比较,-xx为比较符号,结果与条件真假相同。例如:

1
2
3
if [ 8 -gt 5 ]; then
echo "true"
fi

上述脚本判断8大于5的真假性,根据得到的结果选择是否执行后续命令,显然条件结果为真,因此执行后续命令echo "true"

字符串比较

字符串比较有下表几种操作:

用法 描述
[ str1 = str2 ] 相同
[ str1 != str2 ] 不相同
[ str1 \> str2 ] 大于
[ str1 \< str2 ] 小于
[ -n str ] 字符串长度不为0
[ -z str ] 字符串长度为0

需要注意的是字符串大小判断需要注意两点:

  • 大于号和小于号必须转义,否则将会被视作重定向符,从而导致严重错误;
  • 大于和小于顺序和sort命令采取的不同。主要是因为sort命令处理大写字母的方法刚好和test命令相反,即test认为大写字母小于小写字母,而sort则反之。

文件比较

字符串比较有下表几种操作:

用法 描述
[ -d file ] 是否是目录
[ -e file ] 是否存在
[ -f file ] 是否是文件
[ -r file ] 是否可读
[ -s file ] 是否非空
[ -w file ] 是否可写
[ -x file ] 是否可执行
[ -O file ] 是否当前用户所有
[ -G file ] 文件归属组是否与当前用户所在组相同
[ file1 -nt file2 ] newer than文件1比文件2新
[ file1 -ot file2 ] older than文件1比文件2旧

注意:-e外,其他命令当文件不存在时条件的结果均为假,即文件必须存在才有可能条件为真。

布尔运算

if条件控制可以测试复合条件,即进行布尔运算,有以下两种用法:

1
2
[ condition1 ] && [ condition2 ]  # 与运算
[ condition1 ] || [ condition2 ] # 或运算

高级特性

使用双括号

双括号命令提供了使用高级数学表达式的便捷方式,除了提供标准的加减乘除和比较之外,还提供了下表中的运算(双括号中的大于小于号不用转义):

符号 描述
val++ 后增
val-- 后减
++val 先增
--val 先减
! 逻辑求反
~ 位求反
** 求幂
<< 左移
>> 右移
& 位与
` `
&& 逻辑与
`

注意:使用中注意空格

使用双方括号

双方括号提供了字符串比较的高级用法,不仅提供了test中字符串的标准用法,还提供正则匹配的用法,格式为:

1
[[ expression ]]

例如:

1
2
3
if [[ "rich" == r* ]]; then  # 这里正则匹配,结果为真
echo "true"
fi

注意: 不是所有Shell都支持双方括号

case命令

case类似于很多变成语言中的switch,是一种分支控制结构,可以简化很多嵌套if的使用情况。使用格式为:

1
2
3
4
5
6
7
8
case variable in
pattern1 | pattern2)
commands1;;
pattern3)
commands2;;
*) # default
commands;;
esac
0%