生物信息学缘起——linux篇(五)if-then-else命令
一、if-then语句
shell中最基本的结构化命令是if-then语句:
if command
thencommands
fi
如果你在用其他编程语言的if-then语句,这种形式可能会让你有点困惑。
在其他编程语言中,if语句之后的对象是一个等式,这个等式的求值结果为TRUE或FALSE。
但bash shell的if语句并不是这么做的。bash shell的if语句会运行if后面的那个命令。
如果该命令的退出状态码(参见第11章)是0(该命令成功运行),位于then部分的命令就会被执行。
如果该命令的退出状态码是其他值,then部分的命令就不会被执行,bash shell会继续执行脚本中的下一个命令。
fi语句用来表示if-then语句到此结束。
例如:
#!/bin/bash
# testing the if statement
if pwd
thenecho "It worked"
fi
pwd命令成功运行,屏幕会打印“It worked”。
否则:
#!/bin/bash
# testing a bad command
if IamNotaCommand
thenecho "It worked"
fiecho "We are outside the if statement"
乱码的命令不执行,返回正数,为错误值,不执行then后的语句,因此输出“We are outside the if statement”。
二、if-then-else语句
在if-then语句中,不管命令是否成功执行,你都只有一种选择。如果命令返回一个非零退出状态码,bash shell会继续执行脚本中的下一条命令。在这种情况下,如果能够执行另一组命令就好了。这正是if-then-else语句的作用:
if command
thencommands
elsecommands
fi
例如:
#!/bin/bash
# testing the else section
testuser=NoSuchUser
if grep $testuser /etc/passwd
thenecho "The bash files for user $testuser are:"ls -a /home/$testuser/.b*
elseecho "The user $testuser does not exist on this system."
fi
if语句行使用grep命令在/etc/passwd文件中查找某个用户名当前是否在系统上使用。如果有
用户使用了那个登录名,脚本会显示一些文本信息并列出该用户HOME目录的bash文件。
显然“NoSuchUser”并不是我的用户名,因此执行else后的内容,输出“The user NoSuchUser does not exist on this system”。
三、嵌套if-then
有时你需要检查脚本代码中的多种条件。对此,可以使用嵌套的if-then语句。
要检查/etc/passwd文件中是否存在某个用户名以及该用户的目录是否尚在,可以使用嵌套的
if-then语句。嵌套的if-then语句位于主if-then-else语句的else代码块中。
例如,要检查/etc/passwd文件中是否存在某个用户名以及该用户的目录是否尚在,可以使用嵌套的if-then语句。嵌套的if-then语句位于主if-then-else语句的else代码块中。
#!/bin/bash
# Testing nested ifs
#
testuser=NoSuchUser
#
if grep $testuser /etc/passwd
thenecho "The user $testuser exists on this system."
elseecho "The user $testuser does not exist on this system."if ls -d /home/$testuser/thenecho "However, $testuser has a directory."fi
fi
这个脚本准确无误地发现,尽管登录名已经从/etc/passwd中删除了,但是该用户的目录仍然存在。
在脚本中使用这种嵌套if-then语句的问题在于代码不易阅读,很难理清逻辑流程。
可以使用else部分的另一种形式:elif。
这样就不用再书写多个if-then语句了。elif使用另一个if-then语句延续else部分。
if command1
thencommands
elif command2
thenmore commands
fi
elif语句行提供了另一个要测试的命令,这类似于原始的if语句行。如果elif后命令的退出状态码是0,则bash会执行第二个then语句部分的命令。使用这种嵌套方法,代码更清晰,逻辑更易懂。
更进一步,让脚本检查拥有目录的不存在用户以及没有拥有目录的不存在用户:
#!/bin/bash
# Testing nested ifs - use elif & else
#
testuser=NoSuchUser
#
if grep $testuser /etc/passwd
thenecho "The user $testuser exists on this system."
#
elif ls -d /home/$testuser
thenecho "The user $testuser does not exist on this system."echo "However, $testuser has a directory."
#
elseecho "The user $testuser does not exist on this system."echo "And, $testuser does not have a directory."
fi
这段代码检查所给用户是否在此系统中,如果有,则输出“The user $testuser exists on this system”,并列出其目录;
如果没有但登录过,则输出“The user $testuser does not exist on this system,However, $testuser has a directory”;
如果这个用户从没在服务器存在过,则输出“The user $testuser does not exist on this system,And, $testuser does not have a directory”。
四、test语句
if-then语句有一个限制,那就是它只能检测退出码。因此,我们需要另一个命令——test,来检测退出码之外的条件。
test condition
与if-then联用时,它是这样的:
if test condition
thencommands
fi
如果不写test命令的condition部分,它会以非零的退出状态码退出,并执行else语句块。
另外,bash shell提供了“[ ]”,无需在if-then语句中声明test命令,这方便了很多。
注意,第一个方括号之后和第二个方括号之前必须加上一个空格,否则就会报错。
if [ condition ]
thencommands
fi
test命令可以判断三类条件:数值比较、字符串比较、文件比较
(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 |
例如:
#!/bin/bash
# Using numeric test evaluations
value1=10
value2=11
#
if [ $value1 -gt 5 ]
thenecho "The test value $value1 is greater than 5"
fi
#
if [ $value1 -eq $value2 ]
thenecho "The values are equal"
elseecho "The values are different"
fi
别忘了,shell只能处理整数,所以不要比较浮点数!
(2)字符串比较
比 较 | 描 述 |
---|---|
str1 = str2 | 检查str1是否和str2相同 |
str1 != str2 | 检查str1是否和str2不同 |
str1 < str2 | 检查str1是否比str2小 |
str1 > str2 | 检查str1是否比str2大 |
-n str1 | 检查str1的长度是否非0 |
-z str1 | 检查str1的长度是否为0 |
注意,“<”“>”需要前加“\”转义,否则会被当做重定向!
(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旧 |
五、复合条件测试
if-then语句允许你使用布尔逻辑来组合测试。有两种布尔运算符可用:
(1) [ condition1 ] && [ condition2 ]
(2)[ condition1 ] || [ condition2 ]
第一种布尔运算使用AND布尔运算符来组合两个条件。要让then部分的命令执行,两个条件都必须满足。
第二种布尔运算使用OR布尔运算符来组合两个条件。如果任意条件为TRUE,then部分的命令就会执行。
六、if-then高级特性
1、双括号
(( expression ))
双括号命令允许你在比较过程中使用高级数学表达式。但shell数学表达是弱项,平日也少用shell计算,所以这段略过。
2、双方括号
[[ expression ]]
双方括号里的expression使用了test命令中采用的标准字符串比较。但它提供了test命令未提供的另一个特性——模式匹配。
在模式匹配中,可以定义一个正则表达式来匹配字符串值。
#!/bin/bash
# using pattern matching
#
if [[ $USER == r* ]]
then
echo "Hello $USER"
else
echo "Sorry, I do not know you"
fi
在上面的脚本中,我们使用了双等号(==)。双等号将右边的字符串(r*)视为一个模式,并应用模式匹配规则。双方括号命令$USER环境变量进行匹配,看它是否以字母r开头。如果是的话,比较通过,shell会执行then部分的命令。
七、case命令
你会经常发现自己在尝试计算一个变量的值,在一组可能的值中寻找特定值。
在这种情形下,你不得不写出很长的if-then-else语句,就像下面这样。
#!/bin/bash
# looking for a possible value
#
if [ $USER = "rich" ]
thenecho "Welcome $USER"echo "Please enjoy your visit"
elif [ $USER = "barbara" ]
thenecho "Welcome $USER"echo "Please enjoy your visit"
elif [ $USER = "testing" ]
thenecho "Special testing account"
elif [ $USER = "jessica" ]
thenecho "Do not forget to logout when you're done"
elseecho "Sorry, you are not allowed here"
fi
学会case命令后,就不需要再写出所有的elif语句来不停地检查同一个变量的值了。
case命令会采用列表格式来检查单个变量的多个值。
case variable in
pattern1 | pattern2) commands1;;
pattern3) commands2;;
*) default commands;;
esac
case命令会将指定的变量与不同模式进行比较。如果变量和模式是匹配的,那么shell会执行为模式指定的命令。可以通过竖线操作符在一行中分隔出多个模式模式。星号会捕获所有与已知模式不匹配的值。
我们可把上述if-the-else语句简化为:
#!/bin/bash
# using the case command
#
case $USER in
rich | barbara)echo "Welcome, $USER"echo "Please enjoy your visit";;
testing)echo "Special testing account";;
jessica)echo "Do not forget to log off when you're done";;
*)echo "Sorry, you are not allowed here";;
esac
参考资料:《linux命令行与shell脚本编程大全.第三版》
生物信息学缘起——linux篇(五)if-then-else命令相关推荐
- 生物信息学缘起——linux篇(六)for和while循环
一.for循环语句 在linux中,for循环语句的逻辑和使用方法与其他编程语言类似,允许你创建一个遍历一系列值的循环,每次迭代都使用其中一个值来执行已定义好的一组命令. for var in lis ...
- 生物信息学缘起——linux篇(四):shell编程
一.Hello World! 让我们先从最简单的编程开始: # 创建一个Helloword.sh 文件 touch Helloword.sh# 编辑Helloword.sh 文件 vim Hellow ...
- Linux 的五个关机重启命令
一.Linux 的五个关机重启命令 1.shutdown 2.poweroff 3.init 4.reboot 5.halt 二.具体说明 在linux下一些常用的关机/重启命令有shutdown.h ...
- 软件测试基础篇五App之adb命令
命令优势:效率高 面试会问 工具的本质也是调用命令 解决工具的能力边界 ADB可以用来安装卸载软件.管理安卓系统软件.启动测试.抓取操作日志等 一.常用命令 1.查看已连接的设备列表:adb devi ...
- 为啥linux分区是nvme0n1,NAS 篇五:尝试达成最终目标: 黑裙+万兆网卡+Nvme 存储空间的实现与测试...
NAS 篇五:尝试达成最终目标: 黑裙+万兆网卡+Nvme 存储空间的实现与测试 2020-01-18 18:49:23 46点赞 248收藏 80评论 创作立场声明:1. 本系列文章讨论NAS与局域 ...
- 硬盘底座linux,微客智品 篇五十二:机械硬盘如何安放?用奥睿科单盘位移动硬盘底座助力新玩法...
微客智品 篇五十二:机械硬盘如何安放?用奥睿科单盘位移动硬盘底座助力新玩法 2020-01-07 15:36:58 1点赞 10收藏 30评论 随着新一代M.2硬盘的流行与普及,3.5寸机械硬盘愈发变 ...
- ds存储查看 linux,我的NAS我的地盘 篇五:群晖NAS软件介绍与应用之DS Audio篇
我的NAS我的地盘 篇五:群晖NAS软件介绍与应用之DS Audio篇 2019-03-01 14:11:20 35点赞 567收藏 51评论 前言 继续昨天的话题,前文介绍了群晖下的视频播放管理器D ...
- Linux篇:Shell脚本实现Gitlab双备份
01 前言 最近成功从架构组拿到了Gitlab的管理权限,第一件事就是想着如何备份,以防数据丢失背大锅,于是在网上搜索一番,发现一段非常赞的备份脚本,记录照着操作一下: 参考文章:https://bl ...
- 黑群辉安装php,黑群晖从装机到使用全过程 篇五:群晖安装VirtualBox虚拟机
黑群晖从装机到使用全过程 篇五:群晖安装VirtualBox虚拟机 2017-10-13 21:29:39 33点赞 312收藏 28评论 经常喜欢折腾电脑的童鞋一定知道虚拟机,在自己的电脑上可以安装 ...
最新文章
- mybatis开发dao的方法——(三)
- QML编程之旅 -- 事件处理
- Docker基本组成 和 基本命令
- 格力:今日投放12万只格力口罩 明日起增至16万只
- 读后感:软件测试经验与教训
- jquery ajax 访问 mysql_使用ajax+jquery+php访问mysql数据库,并且达到不跳转页面的效果。。。...
- POJ3250 Bad Hair Day【单调递减队列+堆栈】
- 持续集成~Jenkins构建GitHub项目的实现
- 【STM32】STM32CubeMX使用FreeRTOS教程1----定时器学习
- 电脑打开应用程序提示配置系统未能初始化--解决方案
- html span 文字垂直居中,p标签中的span标签文字垂直居中对齐
- 免费公共DNS服务器大全
- 车联网智能终端GB/T 32960国标协议规范 、国标新能源车联网终端GB/T32960标准T-BOX应用
- EMC 电路设计基础
- 夹缝中的垂直母婴电商贝莱优品们:生存之道怎么挖?
- HBuilderX初次使用
- 跟潭州学院的强子老师学习网络爬虫---爬取全书网
- 矩阵相似,矩阵合同,矩阵等价概念总结
- 信贷客户调查中最需关注的十个方面(附经典案例解析)
- 有限差分法电磁场matlab,有限差分法的分析电磁场边值问题(定稿).doc