和大多数语言一样,shell脚本中也有一些逻辑控制语句
简单目录
- 1.if语句
–if-then
–if-then-else
–if-then-elif - 2.test命令
–数值比较
–字符串比较
–文件比较 - 3.使用逻辑表达式
- 4.更高级的表达式处理能力
–双括号
–双中括号 - 5.case命令
- 6.for命令
- 7.while命令
- 8.until命令
- 9.退出循环
1.if语句
if-then语句
结构格式
if command
then
commands
fi
command
参数不是布尔值,而是一个命令的退出状态码,如果退出状态码是0,则执行then后面的语句,fi
是结束标志
if-then另外一种写法
if command; then
commands
fi
if-then-else语句
结构格式
if command
then
commands
else
commands
fi
和if-then功能相同,区别是command
退出状态码不为0时,执行else后面的语句
*注意 if-then和if-then-else都支持嵌套使用
if-then-elif语句
结构格式
if command1
then
commands
elif command2
then
commands
fi
2.test命令
if
语句中,if
后面判断的是结束状态码,这个对于开发来说不是很友好,可以通过test
命令判断更多的东西
配合if
语句,结构格式如下
if test condition
then
commands
fi
*注意 test
会返回一个状态码,然后会根据状态码决定后面的执行
*注意 如果test
后面没有condition,则test
命令返回的是非0的状态码
*注意 bash shell提供了另外一种测试条件的方法,不需要test
命令,只要将条件放在[]
中即可
数值比较
符号 | 描述 |
---|---|
-eq | 等于 |
-eg | 大于等于 |
-gt | 大于 |
-le | 小于等于 |
-lt | 小于 |
-ne | 不等于 |
举例
if test 5 -eg 4
then
echo "大于等于"
fi
*注意 数值比较不支持浮点数
字符串比较
符号 | 描述 |
---|---|
= | 等于 |
!= | 不等于 |
< | 小于 |
> | 大于 |
-n | 长度是否非0 |
-z | 长度是否为0 |
*注意 使用>
、<
时要用转义字符\
否则会认为是重定向的标志
文件比较
符号 | 描述 |
---|---|
-d | 是否存在并是一个目录 |
-e | 是否存在 |
-f | 是否存在并是一个文件 |
-r | 是否存在并可读 |
-s | 是否存在并非空 |
-w | 是否存在并可写 |
-x | 是否存在并执行 |
-O | 是否存在并属于当前用户 |
-G | 是否存在并默认组与当前用户相同 |
-nt | 文件1是否比文件2新 |
-ot | 文件1是否比文件2旧 |
3.逻辑表达式
shell脚本支持的逻辑表达式有两个&&
(与)、||
(或)
4.更高级的表达式处理能力
双括号
双括号((expression))
中的expression参数支持更多的数学表达式符号,如下
符号 | 描述 |
---|---|
val++ | 后自增 |
val– | 后自减 |
++val | 前自增 |
–val | 前自减 |
! | 逻辑反 |
~ | 位求反 |
** | 幂运算 |
<< | 左位移 |
>> | 右位移 |
& | 位布尔和 |
| | 位布尔或 |
&& | 逻辑和 |
|| | 逻辑或 |
双方括号
双方括号[[expression]]
中的expression参数支持字符串操作表达式并且支持正则表达式
*注意 bash shell完美支持双方括号,但是不是所有的shell都支持
5.case命令
case命令可以避免写多个elif的情况,结构如下
case variable in
pattern1 | pattern2) commands1;;
pattern2) commands2;;
*) default commands;;
esac
variable
是变量
pattern
是比较的值
*
是default的意思
*注意 格式中的半括号)
、双分号;;
等语法
6.for命令
结构格式
for var in list
do
commands
done
类似其他编程语言的for-in语句,list是一系列值,下面是添加list的几种方法
1.从列表中读取
列表中各个值之间以空格区分,如果列表中要把带空格的归为一个值,可以用""
将其包裹起来
例如aaa bbb ccc "ddd eee" fff
,其中的"ddd eee"
是一个值
2.从变量中读取
将一串值付给一个变量,for命令会挨个读取变量中的值
3.从命令中读取,看下面的例子
shell脚本代码
#!/bin/bash
file="file1"
for state in $(cat $file)
do
echo "visti $state"
done
file1文件内容
aaa
bbb
ccc
ddd eee
执行脚本结果
➜ ~ ./test
visti aaa
visti bbb
visti ccc
visti ddd
visti eee
bash shell默认以三个标识表示字段的分割,分别是空格、制表符、换行符,他们用IFS环境变量控制,可以自定义字段分割符
IFS=$'\n'
这样的话,在该命令后面的语句都会只以换行符作为字段的分割符,例如前面的脚本改成如下
#!/bin/bash
file="file1"
IFS=$'\n'
for state in $(cat $file)
do
echo "visti $state"
done
执行结果如下
➜ ~ ./test
visti aaa
visti bbb
visti ccc
visti ddd eee
如果要用多个分割值,只要用串联起来就行
IFS=$'\n':;"
上面的语句会将换行符、冒号、分号、双引号当做分割符
4.用通配符读取目录
如下语句
for file in /home/rich/*
通配符*
会遍历rich下得所有file
5.支持C语言风格的for语句
将C语言风格的语句用(())
包裹起来即可,写起来类似这样
for ((i=1; i<10; i++))
do
echo $i
done
7.while命令
结构格式
while test command
do
other commands
done
*注意 while循环会在test退出状态码不为0是结束
*注意 while后面可以跟多个测试语句
8.until命令
until和while正好相反,会在test退出状态码不为0是执行,为0则退出
结构格式
until test command
do
other commands
done
*注意 这些循环命令都可以嵌套使用
9.退出循环
break命令 跳出循环
continue命令 跳出本次循环