生物信息学缘起——linux篇(五)if-then-else命令

一、if-then语句

shell中最基本的结构化命令是if-then语句:

if command
then
    commands
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
then
    echo "It worked"
fi

pwd命令成功运行,屏幕会打印“It worked”。

否则:

#!/bin/bash
# testing a bad command
if IamNotaCommand
then
    echo "It worked"
fi
    echo "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
then
    commands
else
    commands
fi

例如:

#!/bin/bash
# testing the else section
testuser=NoSuchUser
if grep $testuser /etc/passwd
then
    echo "The bash files for user $testuser are:"
    ls -a /home/$testuser/.b*
else
    echo "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
then
    echo "The user $testuser exists on this system."
else
    echo "The user $testuser does not exist on this system."
    if ls -d /home/$testuser/
    then
        echo "However, $testuser has a directory."
    fi
fi

这个脚本准确无误地发现,尽管登录名已经从/etc/passwd中删除了,但是该用户的目录仍然存在。

在脚本中使用这种嵌套if-then语句的问题在于代码不易阅读,很难理清逻辑流程。

可以使用else部分的另一种形式:elif。

这样就不用再书写多个if-then语句了。elif使用另一个if-then语句延续else部分。

if command1
then
    commands
elif command2
then
    more commands
fi

elif语句行提供了另一个要测试的命令,这类似于原始的if语句行。如果elif后命令的退出状态码是0,则bash会执行第二个then语句部分的命令。使用这种嵌套方法,代码更清晰,逻辑更易懂。

更进一步,让脚本检查拥有目录的不存在用户以及没有拥有目录的不存在用户:

#!/bin/bash
# Testing nested ifs - use elif & else
#
testuser=NoSuchUser
#
if grep $testuser /etc/passwd
then
    echo "The user $testuser exists on this system."
#
elif ls -d /home/$testuser
then
    echo "The user $testuser does not exist on this system."
    echo "However, $testuser has a directory."
#
else
    echo "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
then
    commands
fi

如果不写test命令的condition部分,它会以非零的退出状态码退出,并执行else语句块。

另外,bash shell提供了“[ ]”,无需在if-then语句中声明test命令,这方便了很多。

注意,第一个方括号之后和第二个方括号之前必须加上一个空格,否则就会报错。

if [ condition ]
then
    commands
fi

test命令可以判断三类条件:数值比较、字符串比较、文件比较

(1)数值比较

表1 test命令的数值比较功能
比 较描 述
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 ]
then
    echo "The test value $value1 is greater than 5"
fi
#
if [ $value1 -eq $value2 ]
then
    echo "The values are equal"
else
    echo "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" ]
then
    echo "Welcome $USER"
    echo "Please enjoy your visit"
elif [ $USER = "barbara" ]
then
    echo "Welcome $USER"
    echo "Please enjoy your visit"
elif [ $USER = "testing" ]
then
    echo "Special testing account"
elif [ $USER = "jessica" ]
then
    echo "Do not forget to logout when you're done"
else
    echo "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脚本编程大全.第三版》

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值