简介
- 对shell脚本中的命令施加一些逻辑流程控制。有一类命令会根据条件使脚本跳过某些命令,根据条件去执行指定的命令。这样的命令通常称为结构化命令(structured command)
- 结构化命令允许你改变程序执行的顺序。
if语法格式
单分支 | 双分支 | 多分支 |
---|---|---|
if command;then
commands fi |
if command;then
commands else commands fi |
if command;then
commands elif commands elif commands … .else commands fi |
bash shell的if语句会运行if后面的那个命令。如果该命令的退出状态码是0,位于then部分的明星就会被执行。如果该命令的退出状态码是其他值,then部分的命令就不会被执行,bash shell会继续执行脚本中的下一个命令。fi语句用来表示if-then语句到此结束。
if语句可以多层嵌套使用,每块命令都会根据命令是否会返回退出状态码买执行。记住,只有第一个返回退出状态码0的语句中的then部分会被执行。
test命令
- test命令提供了在if-then语句中测试不同条件的途径。如果test命令中列出的条件成立,test命令就会退出并返回退出状态码0,条件不成立,test命令就会返回非0的退出状态码。
格式:
test condition
例如:
if test condition ;then
commands
fi
- bash shell提供了另一种条件测试的方法,无需在if-then语句中声明test命令。如下:
if [ condition ] ;then
commands
fi
方括号定义了测试条件。第一个括号之后和第二个括号之前必须添加空格,否则就会报错。
- test命令可以判断三类条件:
- 数值比较
- 字符串比较
- 文件比较
数值比较
test命令的数值比较功能,也可以使用中括号括起来。
比较 | 描述 |
---|---|
n -eq m | 检查n是否与m相等 |
n -ge m | 检查n是否大于或等于m |
n -gt m | 检查n是否大于m |
n -le m | 检查n是否小于或等于m |
n -lt m | 检查n是否小于m |
n -ne m | 检查n是否不等于m |
例:
#!/bin/bash
m=1
n=2
if [ $m -gt $n ];then
echo "$m is greater than $n"
else
echo "$m is less than $n"
fi
bash shell只能处理整数。echo语句可以正常显示浮点数,test命令中不能使用浮点数。
字符串比较
条件测试还允许比较字符串值。字符串的比较是非常繁琐的。
比较 | 描述 |
---|---|
str1 = str2 | 检查str1是否和str2相同 |
str1 !=str2 | 检查str1是否和str2不同 |
str1 < str2 | 检查str1是否比str2小 |
str1 > str2 | 检查str1是否比str2大 |
-n str1 | 检查str1的长度是否非0 ,长度不为0为假,长度为0为真 |
-z str1 | 检查str1的长度是否为0 ,长度不为0为真,长度为0为假 |
- 字符串相等性
严格区分大小写 - 字符串顺序
测试字符串大于或小于功能需要注意:
- 大于号和小于号必须转义,否则shell会把他们当做重定向符号,把字符串当做文件名;
- 大于和小于排序的顺序和sort命令采用的方式不同。在比较测试中,大写字符被认为小于小写字母,比较测试使用的是标准ASCII顺序。
[root@localhost ~]# [ "a" \> "b" ] ;echo $?
1
[root@localhost ~]#
# test排序a小于b
说明:
test命令和测试表达式使用标准的数学比较符号来表示字符串比较,而用文本代码来表示数值比较。
- 字符串空值测试
-n str1:str1长度为非0返回状态码为0
-z str1:str1长度为0返回状态码为0
[root@localhost ~]# [ -n $a ];echo $?
0
[root@localhost ~]# [ -n "$a" ];echo $?
1
[root@localhost ~]#
#变量a未定义,测试字符串建议使用“"”引起来,当变量未定义会产生歧义,实际执行过程为[ -n ],把-n当成测试条件,返回状态码为0
文件比较
测试linux文件系统上文件和目录的状态。
比较 | 描述 |
---|---|
-d file | 检查file是否存在且为一个目录 |
-e file | 检查file是否存在 |
-f file | 检查file是否存在且为一个文件 |
-r file | 检查file是否存在且可读 |
-s file | 检查file是否存在且非空 |
-w file | 检查file是否存在且可读 |
-x file | 检查file是否村子且可执行 |
-O file | 检查file是否存在且属主为当前用户 |
-G file | 检查file是否存在且默认组与当前用户相同 |
file1 -nt file2 | 检查file1是否比file2新 |
file1 -ot file2 | 检查file1是否比file2旧 |
复合条件测试
if-then语句允许使用布尔逻辑来组合测试。有以下两种运算符可用
[ condition1 ] && [ condition2 ]
使用and布尔预算,两个条件都满足,返回状态码才为0,这样才会执行then部分的指令。
[ condition1 ] || [ condition2 ]
使用or布尔运算,任意一个条件为真,then部分的指令就会执行。
if-then的高级特性
双括号(( expression ))
双括号命令允许你在比较过程中使用高级数学表达式。test命令只能在比较中使用简单的算数操作。
符号 | 描述 |
---|---|
val++ | 后增 |
val– | 后减 |
++val | 先增 |
–val | 先减 |
! | 逻辑取反 |
- | 位求反 |
** | 幂运算 |
<< | 左位移 |
>> | 右位移 |
& | 位布尔和 |
| | 位布尔或 |
&& | 逻辑和 |
|| | 逻辑或 |
双方括号[[ expression ]]
双方括号里的expression使用了test命令中采用的标准字符串比较。它提供了test命令未提供的另一个特性——模式匹配(pattern matching)
[[ "$HOSTNAME" == localhost.* ]]
#.*使用模式匹配
[[ "$HOSTNAME" == "localhost.*" ]]
#.*使用引号引起来代表普通字符