Shell学习-08-分支结构if else

114 篇文章 11 订阅
16 篇文章 0 订阅
2.22 Shell if else
  • 和其它编程语言类似,Shell 也支持选择结构,并且有两种形式,分别是 if else 语句和 case in 语句。
  • if 语句:只使用 if 语句,它的语法格式为:
if  condition
then
    statement(s)
fi

condition是判断条件,如果 condition 成立(返回“真”),那么 then 后边的语句将会被执行;如果 condition 不成立(返回“假”),那么不会执行任何语句。

if 检测的是命令的退出状态

注意,最后必须以fi来闭合,fi 就是 if 倒过来拼写。也正是有了 fi 来结尾,所以即使有多条语句也不需要用{ }包围起来。

  • 也可以将 then 和 if 写在一行:
if  condition;  then
    statement(s)
fi

注意 condition 后边的分号;,当 if 和 then 位于同一行的时候,这个分号是必须的,否则会有语法错误。

  • if else 语句:如果有两个分支,就可以使用 if else 语句,它的格式为:
if  condition
then
   statement1
else
   statement2
fi

如果 condition 成立,那么 then 后边的 statement1 语句将会被执行;否则,执行 else 后边的 statement2 语句。

  • 例如使用 if 语句来比较两个数字的大小:
[root@localhost testshell]# touch test6.sh && vi test6.sh
#!/bin/bash
read -p "Enter first num >" a && printf "\n" && 
read -p "Enter second num >" b && printf "\n" &&

if(($a==$b))
then
echo "a、b相同"
	#另一条分支开始
	else
	echo "a、b不同"
	#另一条分支结束
fi	#if结束
#运行结果:
[root@localhost testshell]# . test6.sh
Enter first num >10

Enter second num >10

a、b相同
#a 和 b 相等,判断条件成立,所以执行了 then 后边的语句。
[root@localhost testshell]# . test6.sh
Enter first num >12

Enter second num >10

a、b不同
#a 和 b 不相等,判断条件不成立,所以执行了 else 后边的语句。

(())是一种数学计算命令,它除了可以进行最基本的加减乘除运算,还可以进行大于、小于、等于等关系运算,以及与、或、非逻辑运算。当 a 和 b 相等时,(( $a == $b ))判断条件成立,进入 if,执行 then 后边的 echo 语句。

  • 在判断条件中也可以使用逻辑运算符,例如:
[root@localhost testshell]# touch test7.sh && vi test7.sh
#!/bin/bash
read -p "Enter first num >" a && printf "\n" && 
read -p "Enter second num >" b && printf "\n" &&


if(( $a > $b && $b >= 0 ))
then
echo "a大于b"
else
echo "a小于b"
fi
#运行结果:
[root@localhost testshell]# . test7.sh
Enter first num >5

Enter second num >3

a大于b
[root@localhost testshell]# . test7.sh
Enter first num >1

Enter second num >2

a小于b

&&就是逻辑“与”运算符,只有当&&两侧的判断条件都为“真”时,整个判断条件才为“真”。

即使 then 后边有多条语句,也不需要用{ }包围起来,因为有 fi 收尾。

  • if elif else 语句:Shell 支持任意数目的分支,当分支比较多时,可以使用 if elif else 结构,它的格式为:注意,if 和 elif 后边都得跟着 then。
if  condition1
then
   statement1
elif condition2
then
    statement2
elif condition3
then
    statement3
……
else
   statement
fi
  • 整条语句的执行逻辑为:

    • 如果 condition1 成立,那么就执行 if 后边的 statement1;如果 condition1 不成立,那么继续执行 elif,判断 condition2。
    • 如果 condition2 成立,那么就执行 statement2;如果 condition2 不成立,那么继续执行后边的 elif,判断 condition3。
    • 如果 condition3 成立,那么就执行 statement3;如果 condition3 不成立,那么继续执行后边的 elif。
    • 如果所有的 if 和 elif 判断都不成立,就进入最后的 else,执行 statement。
  • 例子:输入一个整数,输出该整数对应的星期几的英文表示:

[root@localhost testshell]# touch test8.sh && vi test8.sh
#!/bin/bash
read -p "enter a num >" num && printf "\n" &&

if((num==1)); then
    echo "Monday"
elif((num==2)); then
    echo "Tuesday"
elif ((num==3)); then
    echo "Wednesday"
elif ((num==4)); then
    echo "Thursday"
elif ((num==5)); then
    echo "Friday"
elif ((num==6)); then
    echo "Saturday"
elif ((num==7)); then
    echo "Sunday"
else
    echo "enter error!"
fi
#运行结果
[root@localhost testshell]# . test8.sh
enter a num >8

enter error!
[root@localhost testshell]# . test8.sh
enter a num >5

Friday

2.23 Shell退出状态
  • 每一条 Shell 命令,不管是 Bash 内置命令(例如 cd、echo),还是外部的 Linux 命令(例如 ls、awk),还是自定义的 Shell 函数,当它退出(运行结束)时,都会返回一个比较小的整数值给调用(使用)它的程序,这就是命令的退出状态(exit statu)

很多 Linux 命令就是一个C语言程序,main() 函数的最后都有一个return 0,如果程序想在中间退出,还可以使用exit 0,这其实就是C语言程序的退出状态。当有其它程序调用这个程序时,就可以捕获这个退出状态。

if 语句的判断条件,从本质上讲,判断的就是命令的退出状态。

退出状态为 0 表示“成功”;也就是说,程序执行完成并且没有遇到任何问题。除 0 以外的其它任何退出状态都为“失败”。

“惯例”而非“规定”,是因为也会有例外,比如 diff 命令用来比较两个文件的不同,对于“没有差别”的文件返回 0,对于“找到差别”的文件返回 1,对无效文件名返回 2。

Shell 的这个部分与你所熟悉的其它编程语言正好相反:在C语言、C#、Java中,0 表示“假”,其它值表示“真”。

  • 在 Shell 中,有多种方式取得命令的退出状态,其中 $? 是最常见的一种。
[root@localhost testshell]# $?
-bash: 0: 未找到命令
[root@localhost testshell]# echo $?
127
[root@localhost testshell]# ll
总用量 32
-rw-r--r-- 1 root root 237 11月 28 13:09 test1.sh
-rw-r--r-- 1 root root  78 11月 28 12:21 test2.sh
[root@localhost testshell]# echo $?
0
#判断值相等
[root@localhost testshell]# echo $a
1
[root@localhost testshell]# echo $b
2
[root@localhost testshell]# (($b == $b))
[root@localhost testshell]# echo $?
0
[root@localhost testshell]# (($a == $b))
[root@localhost testshell]# echo $?
1

  • 退出状态和逻辑运算符的组合:Shell if 语句是允许我们使用逻辑运算符将多个退出状态组合起来,这样就可以一次判断多个条件了。
运算符使用格式说明
&&expression1 && expression2逻辑与运算符,当 expression1 和 expression2 同时成立时,整个表达式才成立。 如果检测到 expression1 的退出状态为 非0,就不会再检测 expression2 了,因为不管 expression2 的退出状态是什么,整个表达式必然都是不成立的,检测了也是多此一举。
||expression1 || expression2逻辑或运算符,expression1 和 expression2 两个表达式中只要有一个成立,整个表达式就成立。 如果检测到 expression1 的退出状态为 1,就不会再检测 expression2 了,因为不管 expression2 的退出状态是什么,整个表达式必然都是成立的,检测了也是多此一举。
!!expression逻辑非运算符,相当于“取反”的效果。如果 expression 成立,那么整个表达式就不成立;如果 expression 不成立,那么整个表达式就成立。
  • 将用户输入的 URL 写入到文件中。
#在 Shell 脚本文件所在的目录新建一个文本文件并命名为 urls.txt
[root@localhost testshell]# touch urls.txt
[root@localhost testshell]# touch test9.sh && vi test9.sh
#!/bin/bash
read filename
read url

if test -w $filename && test -n $url
then 
        echo $url > $filename
        echo "ok"
else
        echo "false"
fi
#然后运行 Shell 脚本,运行结果为:
[root@localhost testshell]# . test9.sh
urls.txt             
www.baidu.com
ok
[root@localhost testshell]# cat urls.txt
www.baidu.com
[root@localhost testshell]# . test9.sh
url.txt

false
  • test 是 Shell 内置命令,可以对文件或者字符串进行检测,其中,-w选项用来检测文件是否存在并且可写,-n选项用来检测字符串是否非空。
2.26 Shell case in
  • 和其它编程语言类似,Shell 也支持两种分支结构(选择结构),分别是 if else 语句和 case in 语句。当分支较多,并且判断条件比较简单时,使用 case in 语句就比较方便了。 case in 的用法,它的基本格式如下:
case expression in
    pattern1)
        statement1
        ;;
    pattern2)
        statement2
        ;;
    pattern3)
        statement3
        ;;
    ……
    *)
        statementn
esac
  • case、in 和 esac 都是 Shell 关键字,expression 表示表达式,pattern 表示匹配模式。

    • expression 既可以是一个变量、一个数字、一个字符串,还可以是一个数学计算表达式,或者是命令的执行结果,只要能够得到 expression 的值就可以。
    • pattern 可以是一个数字、一个字符串,甚至是一个简单的正则表达式。
  • case 会将 expression 的值与 pattern1、pattern2、pattern3 逐个进行匹配:

    • 如果 expression 和某个模式(比如 pattern2)匹配成功,就会执行这模式(比如 pattern2)后面对应的所有语句(该语句可以有一条,也可以有多条),直到遇见双分号;;才停止;然后整个 case 语句就执行完了,程序会跳出整个 case 语句,执行 esac 后面的其它语句。
    • 如果 expression 没有匹配到任何一个模式,那么就执行*)后面的语句(*表示其它所有值),直到遇见双分号;;或者esac才结束。*)相当于多个 if 分支语句中最后的 else 部分。

这里的;;*)就相当于其它编程语言中的 break 和 default。

  • *)的几点说明:

    • Shell case in 语句中的*)用来“托底”,万一 expression 没有匹配到任何一个模式,*)部分可以做一些“善后”工作,或者给用户一些提示。
    • 可以没有*)部分。如果 expression 没有匹配到任何一个模式,那么就不执行任何操作。
  • 除最后一个分支外(这个分支可以是普通分支,也可以是*)分支),其它的每个分支都必须以;;结尾,;;代表一个分支的结束,不写的话会有语法错误。最后一个分支可以写;;,也可以不写,因为无论如何,执行到 esac 都会结束整个 case in 语句。

  • 上面的代码是 case in 最常见的用法,即 expression 部分是一个变量,pattern 部分是一个数字或者表达式。

  • 例如,就是输入一个整数,输出该整数对应的星期几的英文表示,这节我们就用 case in 语句来重写代码,如下所示。

[root@localhost testshell]# cp test8.sh test8_1.sh
[root@localhost testshell]# vi test8_1.sh
#!/bin/bash
read -p "enter a num >" num && printf "\n" &&

case $num in
1)
    echo "Monday" ;;
2)
    echo "Tuesday" ;;
3)
    echo "Wednesday" ;;
4)
    echo "Thursday" ;;
5)
    echo "Friday" ;;
6)
    echo "Saturday" ;;
7)
    echo "Sunday" ;;
*)
    echo "enter error!"
esac
#运行结果
[root@localhost testshell]# . test8_1.sh
enter a num >2

Tuesday
[root@localhost testshell]# . test8_1.sh
enter a num >11

enter error!
  • case in 和正则表达式:case in 的 pattern 部分支持简单的正则表达式,具体来说,可以使用以下几种格式:

格式说明
*表示任意字符串。
[abc]表示 a、b、c 三个字符中的任意一个。比如,[15ZH] 表示 1、5、Z、H 四个字符中的任意一个。
[m-n]表示从 m 到 n 的任意一个字符。比如,[0-9] 表示任意一个数字,[0-9a-zA-Z] 表示字母或数字。
|表示多重选择,类似逻辑运算中的或运算。比如,abc | xyz 表示匹配字符串 “abc” 或者 “xyz”。
  • 如果不加以说明,Shell 的值都是字符串,expression 和 pattern 也是按照字符串的方式来匹配的;本节第一段代码看起来是判断数字是否相等,其实是判断字符串是否相等。

  • 最后一个分支*)并不是什么语法规定,它只是一个正则表达式,*表示任意字符串,所以不管 expression 的值是什么,*)总能匹配成功。

  • 如何在 case in 中使用正则表达式:

[root@localhost testshell]# cp test8.sh test8_2.sh
[root@localhost testshell]# vi test8_2.sh
#!/bin/bash

read -n 1 -p "enter a char >" char  &&

case $char in
[a-zA-Z])
    printf "\nletter\n" ;;
[0-9])
    printf "\nDigit\n" ;;
[!?.,])
    printf "\nPunctuation\n" ;;
*)
    printf "\nenter error!\n"
esac
#运行结果
[root@localhost testshell]# . test8_2.sh
enter a char >1
Digit
[root@localhost testshell]# . test8_2.sh
enter a char >d
letter
[root@localhost testshell]# . test8_2.sh
enter a char >	
enter error!

参考文献:
Shell if else语句(详解版)

下一篇:Shell学习-09-分支结构内置命令(test命令、[]、[[]])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值