高级Bash脚本编程指南(6):条件测试结构
来源:互联网 发布:笑郭网络验证破解 编辑:程序博客网 时间:2024/05/24 23:13
成于坚持,败于止步
if/then结构用来判断命令列表的退出状态码是否为0(因为在UNIX惯例, 0表示"成功"), 如果成功的话, 那么就执行接下来的一个或多个命令,有一个专有命令[ (左中括号, 特殊字符). 这个命令与test命令等价, 并且出于效率上的考虑, 这是一个内建命令. 这个命令把它的参数作为比较表达式或者作为文件测试, 并且根据比较的结果来返回一个退出状态码(0 表示真, 1表示假)
条件判断结构如下:
if [ condition-true]thencommand1command2.......elsecommand3command4.......if
如果if和then在条件判断的同一行上的话, 必须使用分号来结束if表达式. if和then都是关键字. 关键字(或者命令)如果作为表达式的开头, 并且如果想在同一行上再写一个新的表达式的话, 那么必须使用分号来结束上一句表达式.
if [ -x "$filename" ]; then
不过同样要注意else if的出现,结构如下
if [condition1]thencommand1......elif[condition2]thencommand2.......elsecommand3.....fi
不过跟我们熟悉的c语言中的判断还是很多不一样,我们看看一个测试条件真假的简单测试程序:
#!/bin/bash# 小技巧:# 如果你不能够确定一个特定的条件该如何进行判断,那么就使用if-test结构. echo "Testing \"0\""if [ 0 ] # zerothenecho "0 is true."elseecho "0 is false."fi # 0 为真.echoecho "Testing \"1\""if [ 1 ] # onethenecho "1 is true."elseecho "1 is false."fi # 1 为真.echoecho "Testing \"-1\""if [ -1 ] # 负1thenecho "-1 is true."elseecho "-1 is false."fi # -1 为真.echoecho "Testing \"NULL\""if [ ] # NULL (空状态)thenecho "NULL is true."elseecho "NULL is false."fi # NULL 为假.echoecho "Testing \"xyz\""if [ xyz ] # 字符串thenecho "Random string is true."elseecho "Random string is false."fi # 随便的一串字符为真.echoecho "Testing \"\$xyz\""if [ $xyz ] # 判断$xyz是否为null, 但是这只是一个未初始化的变量.thenecho "Uninitialized variable is true."elseecho "Uninitialized variable is false."fi # 未定义的初始化为假.echoecho "Testing \"-n \$xyz\""if [ -n "$xyz" ] # 更加正规的条件检查.thenecho "Uninitialized variable is true."elseecho "Uninitialized variable is false."fi # 未初始化的变量为假.echoxyz= # 初始化了, 但是赋null值.echo "Testing \"-n \$xyz\""if [ -n "$xyz" ]thenecho "Null variable is true."elseecho "Null variable is false."fi # null变量为假. echoxyz=1 # 初始化了, 但是赋null值.echo "Testing \"-n \$xyz initilized\""if [ -n "$xyz" ]thenecho "Initilize variable is true."elseecho "Null variable is false."fi echoecho "Testing \"false\""if [ "false" ] # 看起来"false"只不过是一个字符串而已. thenecho "\"false\" is true." #+ 并且条件判断的结果为真.elseecho "\"false\" is false."fi # "false" 为真.echoecho "Testing \"\$false\"" # 再来一个, 未初始化的变量.if [ "$false" ]thenecho "\"\$false\" is true."elseecho "\"\$false\" is false."fi # "$false" 为假.现在, 我们得到了预期的结果.exit 0
看看结果先:root@ubuntu:~/resource/study/shell# ./ifelse-test Testing "0"0 is true.Testing "1"1 is true.Testing "-1"-1 is true.Testing "NULL"NULL is false.Testing "xyz"Random string is true.Testing "$xyz"Uninitialized variable is false.Testing "-n $xyz"Uninitialized variable is false.Testing "-n $xyz"Null variable is false.Testing "-n $xyz initilized"Initilize variable is true.Testing "false""false" is true.Testing "$false""$false" is false.
其实这个结果还是让人感觉挺意外的上面的0,1,-1全部为真,随意字符为真,未初始化变量为假,已初始化变量为真,null为假test,/usr/bin/test,[ ],和/usr/bin/[ 这么多,看的我很晕,其实他们都是等价的
看一个实例验证一下:
#!/bin/bashone=if test -z "$one"thenecho "No command-line arguments."elseecho "First command-line argument is $one."fione=1if test -z "$one"thenecho "No command-line arguments."elseecho "First command-line argument is $one."fitwo=echoif /usr/bin/test -z "$two" # 与内建的"test"命令结果相同. thenecho "No command-line arguments."elseecho "First command-line argument is $two."fitwo=2if /usr/bin/test -z "$two" # 与内建的"test"命令结果相同. thenecho "No command-line arguments."elseecho "First command-line argument is $two."fiechothree=if [ -z "$three" ]thenecho "No command-line arguments."elseecho "First command-line argument is $three."fithree=3if [ -z "$three" ]thenecho "No command-line arguments."elseecho "First command-line argument is $three."fi echofour=if /usr/bin/[ -z "$four" ]thenecho "No command-line arguments."elseecho "First command-line argument is $four."fifour=4if /usr/bin/[ -z "$four" ]thenecho "No command-line arguments."elseecho "First command-line argument is $four."fiechoexit 0
看一看执行结果;root@ubuntu:~/resource/study/shell# ./iftest No command-line arguments.First command-line argument is 1.No command-line arguments.First command-line argument is 2.No command-line arguments.First command-line argument is 3.No command-line arguments.First command-line argument is 4.
上面的验证说明他们是完全等价的,毫无疑问[[ ]]结构和[ ]结构更加通用,在[[ ]]之间的所有字符都不会发生文件名扩展或者单词分割,但是会发生参数扩展和命令替换
#!/bin/bashecho "For [[ ]] test:"file=/etc/passwdif [[ -e $file ]]thenecho "$file exits"elseecho "$file not exits"fiexit 0
结果:root@ubuntu:~/resource/study/shell# ./double For [[ ]] test:/etc/passwd exits
这里-e是用来测试指定文件是否存在的,在这里使用[ ]其实也是一样的使用[[ ... ]]条件判断结构, 而不是[ ... ], 能够防止脚本中的许多逻辑错误. 比如, &&, ||, <, 和> 操作符能够正常存在于[[ ]]条件判断结构中, 但是如果出现在[ ]结构中的话, 会报错
在if后面也不一定非得是test命令或者是用于条件判断的中括号结构( [ ] 或 [[ ]] )
看一个例子吧
#!/bin/bashdir=/dev/passif cd "$dir"thenecho "Now you are in $dir"elseecho "You can't change to $dir"fidir=/dev/charif cd "$dir"thenecho "Now you are in $dir"elseecho "You can't change to $dir"fidir=/dev/passif cd "$dir" 2> /dev/nullthenecho "Now you are in $dir"elseecho "You can't change to $dir"fiexit 0
结果:root@ubuntu:~/resource/study/shell# ./test1 ./test1: line 3: cd: /dev/pass: No such file or directoryYou can't change to /dev/passNow you are in /dev/charYou can't change to /dev/pass
第一个因为没有指定的目录,所以会自动提示第一行的错误提示,同时if检查到返回状态时false,指定目录存在,没有任何疑问,针对第三个出来为什么没有输出信息,因为2> /dev/null会隐藏错误信息
"if COMMAND"结构将会返回COMMAND的退出状态码.
与此相似, 在中括号中的条件判断也不一定非得要if不可, 也可以使用列表结构,列表结构到底是什么,一块通过实例来理解一下
#!/bin/bashvar1=10var2=20[ "$var1" -ne "$var2" ] && echo "$var1 is not equal to $var2"dir=/dev/pass[ -d "$dir" ] || echo "$dir directory does not exist"exit 0结果:
root@ubuntu:~/resource/study/shell# ./test2 10 is not equal to 20/dev/pass directory does not exist这个实例中出现的&& 和 || 就是上面说的列表结构,&&表示前面的返回结果是true则执行后面的echo,|| 表示前面的返回结果是false则指行后面的echo
(( ))结构扩展并计算一个算术表达式的值. 如果表达式的结果为0, 那么返回的退出状态码为1, 或者是"假". 而一个非零值的表达式所返回的退出状态码将为0, 或者是"true". 这种情况和先前所讨论的test命令和[ ]结构的行为正好相反.听起来感觉有点拗口,看实例吧
#!/bin/bash# 算术测试.# (( ... ))结构可以用来计算并测试算术表达式的结果. # 退出状态将会与[ ... ]结构完全相反!(( 0 ))echo "Exit status of \"(( 0 ))\" is $?." # 1(( 1 ))echo "Exit status of \"(( 1 ))\" is $?." # 0(( 5 > 4 )) # 真echo "Exit status of \"(( 5 > 4 ))\" is $?." # 0(( 5 > 9 )) # 假echo "Exit status of \"(( 5 > 9 ))\" is $?." # 1(( 5 - 5 )) # 0echo "Exit status of \"(( 5 - 5 ))\" is $?." # 1(( 5 / 4 )) # 除法也可以.echo "Exit status of \"(( 5 / 4 ))\" is $?." # 0(( 1 / 2 )) # 除法的计算结果 < 1.echo "Exit status of \"(( 1 / 2 ))\" is $?." # 截取之后的结果为 0.(( 1 / 0 )) 2>/dev/null # 除数为0, 非法计算. echo "Exit status of \"(( 1 / 0 ))\" is $?." # 1exit 0结果:
root@ubuntu:~/resource/study/shell# ./test3 Exit status of "(( 0 ))" is 1.Exit status of "(( 1 ))" is 0.Exit status of "(( 5 > 4 ))" is 0.Exit status of "(( 5 > 9 ))" is 1.Exit status of "(( 5 - 5 ))" is 1.Exit status of "(( 5 / 4 ))" is 0.Exit status of "(( 1 / 2 ))" is 1.Exit status of "(( 1 / 0 ))" is 1.上面实例中$? 获取到上面最后一天指令的返回状态,我们看到了跟我们之前看到的结果是相符的,如果表达式的结果为0, 那么返回的退出状态码为1, 或者是"假". 而一个非零值的表达式所返回的退出状态码将为0, 或者是"true". 这种情况和先前所讨论的test命令和[ ]结构的行为正好相反,所以第一条返回状态时1,怎if条件就是false
先到这里了,O(∩_∩)O~
我的专栏地址:http://blog.csdn.net/column/details/shell-daily-study.html
待续。。。
- 高级Bash脚本编程指南(6):条件测试结构
- 《高级Bash脚本编程指南》学习笔记(8)——基础:条件测试结构
- 高级Bash脚本编程指南(17):测试和分支(case与select结构)
- 高级Bash脚本编程指南
- 高级Bash脚本编程指南
- 高级Bash脚本编程指南
- 高级Bash脚本编程指南
- 高级Bash脚本编程指南
- 高级Bash脚本编程指南
- 高级Bash脚本编程指南
- 高级bash脚本编程指南
- 高级Bash脚本编程指南(14):双圆括号结构
- 高级Bash脚本编程指南(7):文件测试操作符
- 高级Bash脚本编程指南学习笔记
- 高级Bash脚本编程指南--网页版
- 高级Bash脚本编程指南(15):循环
- 《高级Bash脚本编程指南》学习笔记(9)——基础:文件测试操作符
- 高级Bash脚本编程
- 判断是否为数字类型 含小数点、负数
- 线程-互斥量mutex
- Linux中find命令用法大全
- 手机棋牌游戏—棋牌游戏发展的必然趋势
- Android 跳转Activity并通过Bundle对象传递数据
- 高级Bash脚本编程指南(6):条件测试结构
- oracle 并发与事务
- Apache+Tomcat集群配置
- IOCP原理-----转载至tiwlin(写的非常不错)
- Linux中上传文件到ftp
- PantechTools使用教程
- 矩形的个数
- 第16章 标准模版库简介 第17章 STL string类
- mysql 用户管理,权限管理,新建用户