目录
6.bash shell 在if-then语句中的一个高级特性:双小括号
7.bash shell 在if-then语句中的另一个高级特性:双方括号
0.命令的退出状态码
shell中运行的每个命令都使用退出状态码(exit status)告诉shell它已经运行完毕,状态码是一个0-255的整数值。
linux提供了专门的变量$?来保存上个已执行命令的退出状态码。以使用echo $?命令来查看$?变量的值,该值会变成由shell所执行的最后一条命令的退出状态码。
0 | 命令成功结束 |
1 | 一般性未知错误 |
2 | 不适合的shell命令 |
126 | 命令不可执行 |
127 | 没找到命令 |
128 | 无效的退出参数 |
128+x | 与Linux信号x相关的严重错误 |
130 | 通过Ctrl+C终止的命令 |
255 | 正常范围之外的退出状态码 |
1.使用if-then语句
"""脚本中的格式:
"""
if command # command可以在下一行写是一样的
then
command # 前面也可以不需要空格,shell默认每一行为一个命令;command也可以在then同一行写,效果也是一样的。
fi
# 多条命令格式
if command11;command12;command...
then
command21;command22;command... # 前面也可以不需要空格
fi
# 或者
if command11
command12
command...
then
command21
command22
command...
fi
"""命令行中的格式"""
if command;then command;fi # 每个命令之间是分号,并且每个关键词之间一定是分号,代表不同的关键词。
# 多条命令
if command11;command12;command13...;then command21;command22;command23...;fi
bash shell的if语句是命令,而不是其他编程语言中的逻辑表达式。运行if后面的命令,如果该命令的退出状态码为0(该命令成功运行),位于then部分的命令就会被执行。如果 该命令的退出状态码是其他值,then部分的命令就不会被执行,fi语句用来表示if-then语句到此结束。
2.使用if-then-else语句
"""脚本中的格式:
"""
if command # command可以在下一行写是一样的
then
command # 前面也可以不需要空格,shell默认每一行为一个命令;command也可以在then同一行写,效果也是一样的。
else
command # 前面也可以不需要空格,shell默认每一行为一个命令;command也可以在else同一行写,效果也是一样的。
fi
# 多条命令格式
if command11;command12;command...
then
command21;command22;command... # 前面也可以不需要空格
else
command31;command32;command... # 前面也可以不需要空格
fi
# 或者
if command11
command12
command...
then
command21
command22
command...
else
command31
command32
command...
fi
"""命令行中的格式"""
if command;then command;else command;fi # 每个命令之间是分号,并且每个关键词之间一定是分号,代表不同的关键词。
# 多条命令
if command11;command12;command13...;then command21;command22;command23...;else command31;command32;command33...;fi
3.嵌套if-then和嵌套elif语句
有时你需要检查脚本代码中的多种条件,这时可使用嵌套的if-then语句。
(1)嵌套的if-then语句可以位于主if-then-else语句的else代码中也可以位于then代码中。
(2)使用else部分的另一种形式:嵌套的elif语句。这样就不用书写多个if-then语句了,elif使用另一个if-then语句延续else部分。
记住:在elif语句中。紧跟其后的else语句属于elif代码块。他们并不属于之前的if-then代码块。
"""脚本中的格式:"""
# 嵌套if-then语句放在else代码块中
if command
then
command
else
if command # 这个语句也可以放在else同一行,即else if command
then
command
else # 看实际需要,也可以不要这个else部分的处理
command
fi # 需要对该if-then语句结尾
fi
# 嵌套if-then语句放在then代码块中
if command
then
command
if command
then
command
else # 看实际需要,也可以不要这个else部分的处理
command
fi # 需要对该if-then语句结尾
else
command
fi
# elif语句(else if)
if command
then
command
elif command
then
command
else # # 该else代码块属于上面的elif代码块,不属于更之前的if-then代码块。
command
fi # 只需要一个fi,因为没有出现if-then语句块。
"""命令行中的格式"""
if command;then command;else if command;else command;fi;fi # 每个命令之间是分号,else if之间没有分号,因为出现了两队if-then,所以需要两个fi结束。
# 多条命令
if command;then command;elif command;else command;fi # 每个命令之间是分号,elif语句作用else if,但是只出现了一对if-then,所以只需要一个fi结束。
4.test命令
if-then语句不能测试命令退出状态码之外的条件,test命令提供了在if-then语句中测试不同条件的途径。如果test命令中列出的条件成立,test命令的推出状态码就是为0,否则返回非零的退出状态码。
特别注意使用方括号的形式,第一个方括号和第二个方括号之间必须加上一个空格。并且比较对象之间必须要加上空格.
方括号是与test命令同义的特殊bash命令。
"""格式:"""
test condition # condition是test命令要测试的一系列参数和值,只能写一个条件。
"""(1)和if-then结合:"""
if test condition # 只能写1个条件。
then
command
else
command
fi
"""(2)无声明test命令的替代方式,使用方括号,是常用的"""
if [ condition ] # 只能写一个条件。特别注意第一个方括号之后和第二个方括号之前必须加上一个空格,否则会报错
then
command
else
command
fi
test命令可以判断三类条件(condition):
数值比较
字符串比较
文件比较注意:比较对象之间必须要加上空格
(1)数值比较
n1 -eq n2 或者
n1 = n2
检查n1是否与n2相等,相等则状态码为0。注意是有空格的
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
检查n1是否不等于n2。注意是有空格的
注意:比较对象之间必须要加上空格,否则不能识别为特殊字符,而是只识别为字符串,则会永远执行正确。
(1)bash shell只能处理整数,如果出现浮点数的数值比较会报错,退出状态码非零。如果只通过echo语句来显示浮点数没有问题,但是在基于数字的函数就不行了。
(2)如果对数值比较使用了数学运算符号(>、<、=,注意大小于号需要转义),shell会将它们当成字符串比较,和数值比较的比较方式完全不一样。
浮点数比较是会报错的
(2)字符串比较
str1 = str2 检查str1是否和str2相同
所有的标点、大小写情况考虑在内。注意相同是一个等于号,不是两个等于号。 str1 != str2
检查str1是否和str2不同 str1 > str2 检查str1是否比str2大 特别注意需要使用转义符号,\>, \<
不然会被shell解释成重定向命令。重定向命令的退出状态码总是0,导致总是执行then语句。
str1 < str2 检查str1是否比str2小
比较的是每个字符的顺序大小,test命令中的测试使用的是标准的ASCII顺序,小写字母比大写字母大。
-n str1 检查str1的长度是否非0 检查一个变量是否含有数据,有数据则是True -z str1 检查str1的长度是否为0 空的和未初始化定义的变量的长度都为0 sort命令将文件的每一行作为比较的单位,相互比较,比较原则是从首字符向后,一次比较每个字符的ASCII码,默认按升序排序后输出
(3)文件比较
可以测试Linux文件系统上文件和目录的状态。使用比较广泛
-e file
检查file是否存在,可以是文件和目录 -d 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旧,但是比较之前不会检查文件是否存在。 (4)单个test命令,内部有多个conditions的逻辑关系。
如果使用在多个test命令之间则会报错,此时需要使用的是&&、||。一定要注意方括号需要空格
5.复合条件(多个condition)的test测试
多个test命令之间的逻辑关系
"""if-then语句允许使用布尔逻辑来组合测试,有两种布尔运算符可以使用:&&和||"""
# []形式的condition测试
if [ consition1 ] && [ condition2 ]
then
command
fi
if [ consition1 ] || [ condition2 ]
then
command
fi
# test语句形式
if test consition1 && condition2
then
command
fi
if test consition1 || condition2
then
command
fi
6.bash shell 在if-then语句中的一个高级特性:双小括号
"""((expression))用来扩展Shell中的算术运算,以及赋值运算,扩展for,while,if条件测试运算.但是里面不能是命令。"""
"""格式:"""
((expression))
((expression))
用来扩展Shell中的算术运算
,以及赋值运算
,扩展for,while,if条件测试运算.但是里面不能是命令。
注意:单括号(),一般用在包含命令var=$(operation)来将operation的输出作为值赋给变量var。
(1)扩展算术运算
可以使用数学运算+-*/,%(取余),**(幂运算),三元运算符a>b?c:d
此时的效果完全等效于章节一的数学运算。注意,里面的大于号是不需要转义的(高级特性)。即:
var=$((operation))等价于var=$[operation].
(2)扩展赋值运算
变量赋值操作详细可参见章节一的用户变量,双括号的赋值运算可以更高级 1)可以用(())重新定义变量,并且值含有变量可以不需要$符号,直接使用。2)支持多个赋值语句用逗号分开。空格是任意的。
(3)扩展for、while、if条件测试运算
可以替换test命令中的数值比较,但是使用的是数学表达式的比较方式,双括号可以使用高级的数学表达式,可以是任意的数学赋值或比较表达式。区别 1)没有条件测试命令[ condition ]的空格要求,空格可以是任意的。2)支持多个表达式用逗号分开。3)虽然不支持test命令的内部逻辑运算(!,-a,-o),但是支持test之间的逻辑运算(&&,||),该运算可以作用于双括号之间,也可以作用于双括号内部。4)只适用于比较数值,但不适用于比较字符串和文件。
7.bash shell 在if-then语句中的另一个高级特性:双方括号
"""双方括号命令提供了针对字符串比较的高级特性,格式如下:"""
[[ expression ]] # 注意的是方框号前后都有空格,和test命令的但括方括号一样的格式
双方括号里的expression使用了test命令中采用的标准字符串比较(意味着test命令中的一些注意事项,比如左右方括号都需要空格,比较符左右两次也需要空格,支持三种方式的比较等,在双方括号也需要遵守和支持的),但它额外提供了test命令未提供的另一个特性——模式匹配(pattern matching),使用双等号(==),将右边的字符串视为一个模式(也就是正则匹配),并应用模式匹配规则。
8.case命令
在一组数据中尝试找寻特定值需要很长的if-then-else语句,但是有了case命令就不需要写出所有的elif语句来不停的检查同一个变量的值。
# 形成一个大的if-then-elif嵌套组合,比较变量找出特定的值
if command1
then
command set 1
elif command2
then
command set 2
elif command3
then
command set 3
elif command4
then
command set 4
else
command set n
fi
case命令如下:
"""case 命令格式如下:"""
case variable in
pattern1 | pattern2) commands1;; # |表示或,这两个条件都可以,输出同一个commands1
pattern3) commands2;;
*) default commands;;
esac
举例如下:
if [[ $USER = "visit1" ]]
then
echo "Welcom $USER, please enjoy your visit! 1"
elif [ $USER = "visit2" ]
then
echo "Welcom $USER, please enjoy your visit! 2"
elif [ $USER = testing ]
then
echo "Special testing account!"
elif [ $USER = "jupy" ]
then
echo "Don't forget to logout when you're done."
elif [ $USER = "root" ]
then
echo "you are the administrator of this system."
else
echo "Sorry, you are not allowed here!"
fi
# 使用case命令如下
case $USER in
visit1) echo "Welcom $USER, please enjoy your visit! 1";;
visit2) echo "Welcom $USER, please enjoy your visit! 2";;
"testing") echo "Special testing account!";;
jupy) echo "Don't forget to logout when you're done.";;
root) echo "you are the administrator of this system.";;
*) echo "Sorry, you are not allowed here!";;
esac