shell脚本编程基础之二(if、case、for、while、until、continue、break语句使用)

在shell脚本编程中,我们可以根据命令的状态结果,判断要不要执行下一步,但是有时候要判断的问题不止一个,甚至对问题本身都要做判断;同时问题的结果有时也不止一个,这时要借助简单的逻辑与和逻辑或,就显得很无力;要完成复杂的任务,需要借助一定的流程控制:顺序执行、选择执行、循环执行、同时在脚本执行过程中,有用户交互输入的需;

if语句

case语句

for语句

while语法

until语句

continue语句

break语句

  1. if语法

   (1)单分支if语句结构

  if expression;then
    statement1
    statement2
    ...
  fi

     expression:表达式可以是整数、字符、文件比较判断、命令;expression的结果为true时,才执行then后面的statement,

     注意:

       (1)expression中使用[ ]、[[ ]]时记得方括号两边要有空格,如何then不想换行写,需要expression后面有“;”结尾,否则语法错误;

       (2)语句最后要有结尾fi,否则语法错误;


 举例:测试用户,存在就问候

[root@xia7 ~]# id xia
uid=1011(xia) gid=1011(xia) groups=1011(xia)
[root@xia7 ~]# 
[root@xia7 ~]# if id xia &>/dev/null;then echo "hell tom";fi
hell tom
[root@xia7 ~]# 
root@xia7 ~]# id tom
id: tom: no such user
[root@xia7 ~]# 
[root@xia7 ~]# if id tom &>/dev/null;then echo "hell tom";fi
[root@xia7 ~]#

    (2)双分支if语句结构

  if expression;then
     statement1
     statement2
     ...
   else
     statement1
     statement2
     ...
  fi

     expression:表达式为true时,执行then后面的statement,表达式为false时,执行else后面的statement;


举例:测试用户存在就问候,否则就添加用户

[root@xia7 ~]# id tom
id: tom: no such user
[root@xia7 ~]# if id tom &>/dev/null;then echo "hell tom";else useradd tom &>/dev/null;echo "tom is add finished";fi
tom is add finished
[root@xia7 ~]# 
[root@xia7 ~]# id xia
uid=1011(xia) gid=1011(xia) groups=1011(xia)
[root@xia7 ~]# 
[root@xia7 ~]# if id xia &>/dev/null;then echo "hell xia";else useradd tom &>/dev/null;echo "xia is add finished";fi
hell xia
[root@xia7 ~]#

 

  (3)多分支if语句结构

 if expression1;then
    statement1
    ...
 elif expression2;then
    statement1
    ...
 else
    statement1
    ...
 fi

    上面的语法中有多个判断条件expression,执行选择顺序是从上往下,只要前面有一个expression的结果为true时,就执行相应后面then的statement,然后退出if语句,如果前面的expression都为false时,就执行else后面的statement;

   注意:

    1.如果后面的expression也为true是,不会执行,只会判断第一结果为true时,执行后面then的statement;


举例:测试年龄段

#!/bin/bash
#

read -p "please input:" age
if [ $age -le 12 ];then
   echo "is a child"
elif [ $age -le 16 ];then
   echo " is a young"
elif [ $age -eq 18 ];then
   echo "is barely of age"
elif [ $age -lt 120 ];then
   echo "

2.case语句

  当有多个判断条件为字符时,在用if语句就显得比较繁琐,结构看起来也不是很清晰,这时使用case语句结构就显得相对比较清晰简明;

 

   case语句结构

case varname in
模式1)
    statement
     ...
    ;;
模式2)
    statement
    ...
    ;;
*)
    statement
    ...
    ;;
esac

   varname为变量名,可以自定义;其值为后面模式定义到的字符;控制流程:in:为关键字,当varname的值为模式1,就执行其后的statement,“;;”两个分号表示执行后退出case语句;跟多分支if语句一样,  一旦匹配到,不会再判断后面;*)表示前面的都匹配不到,就执行这条默认的模式下的statement;

  注意esac结尾;

  模式:可以使用global风格的通配符:

     *:表示任意长度的任意字符

     []表示指定范围内的任意单个字符

     | :表示或者的关系


举例:测试文件类型

#!/bin/bash
#

read -p "please input file name:" file
[[ -z $file ]] && echo "you have not input" && exit 1
[ -e $file ] && echo "you input file not exist" && exit 1

type=`ls -l $file |cut -c 1`

case $type in

l|p|s)
   echo "$file is special file"
   ;;
b|c)
   echo "$file is device file"
   ;;
-)
   echo "$file is flat file"
   ;;
d)
   echo "$file is dir file"
   ;;
*)
   echo "$file is other file"
   ;;
esac

     

3.for循环语句结构

  for varname in list;do
     循环体
     
  done

   for:为keyword varname:为变量名,可以自定义,list为列表值,有多个,do固定格式;done:为结束符;

   流程控制:当执行for时会把list列表中的值取出来赋值给varname变量,执行循环体,执行完循环体后再到列表中取值赋值给变量,直到把列表中的值取完赋值给变量,才结束循环;

   in 列表生成方式:

      1.直接给出列表,例如:tom jerry xiaoming 注意多个值之间用空格分割,甚至特殊字符需要用""或者/转义符 ;

      2.整数列表:

        {stat..end} 

        `seq start [step] end`

        $(seq [start [step] end)

     3.能够返回列表的命令

       $(command):比如ls

       `command`

    4.使用glob风格的通配符

       *.sh

    5.使用特殊变量引用

      $@

      $*

      $1 $1 …

           

   for循环进入条件:列表中有值

   for循环退出的条件:遍历完列表中的值


举例:创建100个空文件

#!/bin/bash
#

for I in {1..100};do

   touch file$I &>/dev/null
   echo "create file$I finished"
done

[root@xia7 ~]# for I in {1..100};do touch file$I &>/dev/null;echo "create file$I finished";done
create file1 finished
create file2 finished
...
create file99 finished
create file100 finished
[root@xia7 ~]#

4.while循环语句结构

while condition;do
    循环体
done

    while:为keyword condition:为条件表达式,do为固定格式,done为结束;

    流程控制:进入循环体之前,先做一次判断,每次执行循环体之前都会做一次判断,condition为true时执行循环体,为false时退出循环

    while循环进入条件:condition为true时

    while循环退出条件: condition为false时


举例:测试100以内的正整数和

vim f1.sh
#!/bin/bash
#

declare -i I=1
declare -i sum=0
while [ $I -le 100 ];do

     sum=$[$sum+$I]
     let I++
done 
  echo "100sum=$sum"
  
[root@xia7 ~]# chmod +x f1.sh    
[root@xia7 ~]# ./f1.sh 
100sum=5050
[root@xia7 ~]#

5.until循环语句结构

until condition;do
  循环体
done

   until:为keyword condition:为条件表达式 do:为固定格式,done:为结束

   流程控制:跟while执行的条件表达式相反,每次进入循环体之前判断condition为false时执行,condition判断为true时退出循环

   until循环进入条件:condition为false时

   until循环退出条件:condition为true时


举例:猜10以内的随机数字

vim f2.sh
#!/bin/bash
#

r=$[$RANDOM%10+1]

read -p "Please input a number:" num
[[ -z $num ]] && echo "you have not input" && exit 1

until [ $num -eq $r ];do
     if [ $num -gt $r ];then
        echo "you guess too big"
     else
        echo "you guess too small"
     fi
     
     read -p "please continue to guess:" num
done
   echo "Good you guess right !!!"
   
[root@xia7 ~]# chmod +x f2.sh
[root@xia7 ~]# ./f2.sh
Please input a number:5
you guess too big
please continue to guess:4
you guess too big
please continue to guess:3
Good you guess right !!!
[root@xia7 ~]#

 

6.循环控制语句

  (1)continue语法结构

while condition;do
   statement1
   ...
   if expression;then
      continue
   fi
    statement
    ...
done

   continue用于循环体中,出现在哪一层的判断中,提前结束当前迭代的循环,进入下一轮判断;

   continue [num]:[num]表示层数 指定退出的循环层次,最内层为第一层;


举例:求100以内偶数之和

#!/bin/bash
#

declare -i ousum=0
declare -i i=0

while [ $i -le 100 ];do
      let i++
      if [ $[$i%2] -eq 1 ] ;then
          continue
      fi  
      let ousum+=$i
done 

  echo "100 oushu sum is:$ousum"

[root@xia7 ~]# chmod +x f3.sh    
[root@xia7 ~]# ./f3.sh 
100 oushu sum is:2550
[root@xia7 ~]# 
[root@xia7 ~]# bash -x f3.sh 
+ declare -i ousum=0
+ declare -i i=0
+ '[' 0 -le 100 ']'
+ let i++
+ '[' 1 -eq 1 ']'
+ continue
+ '[' 1 -le 100 ']'
+ let i++
+ '[' 0 -eq 1 ']'
+ let ousum+=2
+ '[' 2 -le 100 ']'
+ let i++
+ '[' 1 -eq 1 ']'
+ continue
+ '[' 3 -le 100 ']'

  (2)break

while condition;do
   statement1
   ...
   if expression;then
      break
   fi
    statement
    ...
done

   break:用于循环体中,提前结束当前整个循环退出,最内层为第一层;

   可以在死循环中用break,满足条件执行break,

举例:向100以内的用户问好

#!/bin/bash
#

declare -i sum=0
declare -i i=1

while true;do
   echo "hello user$i"

     if [ $i -ge 100 ];then
        break
     fi
    let i++
done


[root@xia6 ~]# bash -x f4.sh
...
hello user99
+ '[' 99 -ge 100 ']'
+ let i++
+ true
+ echo 'hello user100'
hello user100
+ '[' 100 -ge 100 ']'
+ break
[root@xia6 ~]#

总结:

  1.对于选择执行的语句case,只能对表达式为字符型风格的才能使用,if和case语句在执行时匹配到执行完就退出,不会再看下一条的结果是什么;

  2.对于循环语句while和until语句,要把握循环的进入和退出条件,否则造成死循环,无意义的消耗系统资源,对系统负载有影响;

  3.对于控制语句continue语句是结束本次迭代循环,进入下一轮判断,而break是结束退出当前整个循环;

原创文章,作者:xiashixiang,如若转载,请注明出处:http://www.178linux.com/38242

(0)
上一篇 2016-08-21 20:45
下一篇 2016-08-21 20:45

相关推荐

  • Linux用户和组管理

    Linux用户和组管理 Username / UID 管理员:root,0 普通用户 : 1–65535 系统用户 :系统已经已经存在专门用来对系统服务或者系统资源进行管理的 1–499(CentOS 6.X) 1–999 (CentOS 7.X) 登录用户:平时专门做系统管理的用户 500+ (CentOS 6.X) 1000+ (CeentOS 7.X)…

    Linux干货 2017-04-01
  • vim文本编辑器使用

    vim文本编辑器使用

    2017-09-20
  • 马哥教育网络班21期+第2周课程练习

    一、Linux文件管理类命令汇总 1、文件的复制命令:cp 复制命令:cp     cp [OPTION]… [-T] SOURCE DEST     cp [OPTION]… SOURCE… DI…

    Linux干货 2016-07-29
  • Sqlserver2012(主从复制)共享同步日志备份恢复

    SQL Server 2012相对于SQL Server 2008来说,无论是性能还是功能都有一个相当大的提高,甚至可以用“革命”来形容这一次升级。SQL Server 2012使 SQL Server 跻身于企业级数据库行列。在数据高可用性方面,SQL Se…

    Linux干货 2015-10-31
  • 111-puppet

    一.运维层次分类 OS Provision:

    2016-12-04
  • 27期第一周学习小结

    第一周 1. 描述计算机的组成及其功能。 计算机主要组成部分以下五种:运算器,控制器,存储器,输入设备,输出设备。 运算器的功能是对数据进行算术运算与逻辑运算,就是对数据进行加工处理。 控制器的功能是调度二进制程序,数据,内存寻址,以及协调计算机输入设备和输出设备等各计算机部件之间的正常工作。 存储器的功能是存储二进制指令和数据。存储器是编址存储单元。 输入…

    Linux干货 2017-07-15

评论列表(1条)

  • 马哥教育
    马哥教育 2016-08-22 09:49

    态度不够端正,发布前未进行预览,发布后代码都混在一起了。