一、结构化语句
1. if-then
格式如下:
if command
then
commands
fi
bash shell的if语句会运行if行定义的命令。如果该命令的退出状态码是0(该命令运行成功),位于then部分的命令就会执行。如果该命令的退出状态码是其他什么值,位于then部分的命令就不会执行,bash shell继续执行脚本中的下一个命令。
2. if-then-else
if command
then
commands
else
commands
fi
3. 嵌套if
if command1
then
commands
elif command2
then
more commands
fi
二、 test命令
到目前为止,我们所知道的if语句的命令都是普通的shell命令。你可能想知道if语句是否可以测试和命令的退出状态码无关的条件,比如:逻辑运算,答案是:不能。
test命令提供了这种可能,语法如下
test condition
condition是test命令要测试的一系列参数和值。当用于if-then语句时,test命令看起来是这样的:
if test condition
then
commands
fi
而bash shell提供了另一种在if-then语句中声明test的方法:
if [ condition ]
then
commands
fi
方括号中定义了test命令用到的条件。注意,必须在方括号右侧和左侧各加一个空格,否则会报错。
test命令可以判断3类条件:
- 数值比较
- 字符串比较
- 文件比较
2.1. 数值比较
下表列出了比较两个值时可用的参数
比较 | 描述 |
---|---|
n1 -eq n2 | 检查n1和n2是否相等 |
n1 -ge n2 | 检查n1是否大于或等于n2 |
n1 -gt n2 | 检查n1是否大于n2 |
n1 -le n2 | 检查n1是否小于或等于n2 |
n1 -lt n2 | 检查n1是否小于n2 |
n1 -ne n2 | 检查n1是否不等于n2 |
var=10
if [ $var -gt 5 ]
then
echo "$var 大于 5"
fi
var=5.5
if [ $var -gt 5 ]
then
echo "$var 大于5"
fi
第一个例子可以很好的工作,第二个例子会报错。因为test命令也无法处理浮点数。
记住,bash shell能处理的只有整数。当你使用bash计算器时,你可以让shell将浮点数作为字符串值存储进一个变量。如果你只是通过echo显示这个变量,它可以很好的工作,但它无法在基于数字的函数中工作。
2.2. 字符比较
比较 | 描述 |
---|---|
str1 = str2 | 检查str1和str2是否相同 |
str1 != str2 | 检查str1是否和str2不同 |
str1 < str2 | 检查str1是否比str2小 |
str1 > str2 | 检查str1是否比str2大 |
-n str | 检查str的长度是否非0 |
-z str | 检查str的长度是否为0 |
以下几点注意:
- 大于小于符号在使用时,必须转义,,否则shell会把它们当作重定向符号而把字符串值当作文件名;
- 大于小于顺序和sort命令所采用的不同。
- 如果你不确定一个变量的内容,最好在数值或字符串比较中使用它之前先通过-n或-z来测试变量是否有值。
2.3. 文件比较
比较 | 描述 |
---|---|
-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旧 |
3. 复合条件测试
[ condition1 ] && [ condition2 ] 要让then部分执行,两个条件都必须满足
[ condition1 ] || [ condition2 ] 任意一个条件满足即可
4. if-then的高级特性
bash shell有两项较新的扩展,提供了可在if-then语句中使用的高级特性:
- 用于数学表达式的双尖括号
- 用于高级字符串处理功能的双方括号
4.1 双尖括号
格式如下
(( expression ))
expression可以是任意的数学赋值或者比较表达式,除了test命令使用的标准数学运算符,双尖括号还支持以下运算符
符号 | 描述 |
---|---|
val++ | 后增 |
val-- | 后减 |
++val | 先增 |
--val | 先减 |
! | 逻辑求反 |
~ | 位求反 |
** | 幂运算 |
<< | 左位移 |
>> | 右位移 |
& | 位布尔和 |
| | 位布尔或 |
&& | 逻辑和 |
双竖线 | 逻辑或 |
例子
#! /bin/bash
val=10
if (( $val ** 2 > 90 ))
then
(( val2 = $val**2 ))
echo "The square of $val is $val2"
fi
注意:不需要将双尖括号里面的大于号转义,这是双尖括号提供的另一个高级特性。
4.2 双方括号
双方括号提供了针对字符串比较的高级特性,格式如下
[[ expression ]]
双方括号里面的expression除了使用test命令中采用的标准字符串进行比较,还提供另一个特性---模式匹配(pattern matching)
在模式匹配中,你可以定义一个正则表达式来匹配字符串的值。
五、case语句
如果条件过多,可以用case语句来替换if-else语句。case命令会检查单个变量列表格式的多个值:
case variable in
pattern1 | pattern2) commands1;;
pattern3) commands2;;
*) commands3;;
esac
case命令会将指定的变量同不同模式进行比较,如果变量和模式匹配,那么shell执行该模式后的命令。可以通过竖线操作符来分割模式,在一行列出多个模式。星号会捕获跟所有列出的模式都不匹配的值。