设为首页 收藏本站
查看: 853|回复: 0

shell脚本基础进阶(三)----流程控制语句

[复制链接]

尚未签到

发表于 2018-8-29 06:24:58 | 显示全部楼层 |阅读模式
  流程控制语句
  控制语句,即用来实现对程序流程的选择、循环、转向和返回等进行控制的语句。Bash中的控制语句有几种控制语句?额,小编也没统计过,不清楚哎!!按照百度百科的分类(选择语句,循环语句,转向语句)总结了几个。然后看下吧!
  一、选择语句
  1、if……else……fi
  格式:
(1)if CONDITION;then  
    if-true-doing
  
   fi
  
(2)if CONDITION;then
  
    if-true-doing
  
   else
  
    if-false-doing
  
   fi
  
(3)if CONDITION;then
  
    if-true-doing
  
   elif CONDITION;then
  
    if-true-doing
  
   else
  
    if-false-doing
  
   fi
  注:!CONDITION 条件相反
  练习1:如果某路径不存在,则将其创建为目录;否则显示其存在,并显示内容类型
  脚本:if.sh
[root@centos bash]# cat if.sh  
#!/bin/bash
  
#
  
file=/data/test
  
if [ -e $file ];then
  
   echo "$file exists."
  
   file $file
  
else
  
   mkdir -p $file
  
fi
  
[root@centos bash]# ./if.sh
  
[root@centos bash]# ls -d /data/test
  
/data/test
  
[root@centos bash]# ls -dl /data/test
  
drwxr-xr-x. 2 root root 4096 Sep 19 16:35 /data/test
  
[root@centos bash]# ./if.sh
  
/data/test exists.
  
/data/test: directory
  
[root@centos bash]#
  练习2:位置参数与命令引用练习,统计用户任意指定的普通文件的行数
[root@centos bash]# cat 1.sh  
#!/bin/bash
  
if [ -f $1 ];then
  
lines=$(wc -l $1|cut -d ' ' -f1)
  
echo "the $1 have $lines lines."
  
else
  
  echo "the $1 is not exists or not a com file."
  
fi
  
[root@centos bash]# ./1.sh /etc/grub.conf
  
the /etc/grub.conf have 17 lines.
  
[root@centos bash]# ./1.sh /etc/grub
  
the /etc/grub is not exists or not a com file.
  
[root@centos bash]#
  练习3:特殊变量$#和$@使用,输出脚本参数信息
[root@centos bash]# cat 3.sh  
#!/bin/bash
  
echo "you input $# parameters."
  
echo "you input the parameters are $@."
  
[root@centos bash]# ./3.sh 1 2 3
  
you input 3 parameters.
  
you input the parameters are 1 2 3.
  
[root@centos bash]#
  补充知识点:
  bash脚本与用户交互使用的命令read.
  read [options] VAR...
  -p “prompt”  提示信息
  -t timeout   超时时间
  练习4:熟悉read命令的用法,请用户交互输入用户名,并判断创建系统新用户
[root@centos bash]# cat read.sh  
#!/bin/bash
  
read -p "plz input a new username:" -t 10 username
  
if [ -z $username ];then
  
  echo "you input empt,the end."
  
  exit
  
fi
  

  
if id $username &> /dev/null; then
  
  echo "$username exists."
  
else
  
  useradd $username
  
  echo "the new user $username was be added."
  
fi
  
[root@centos bash]# ./read.sh
  
plz input a new username:
  
you input empt,the end.
  
[root@centos bash]# ./read.sh
  
plz input a new username:centos
  
the new user centos was be added.
  
[root@centos bash]# id centos
  
uid=500(centos) gid=500(centos) groups=500(centos)
  
[root@centos bash]# ./read.sh
  
plz input a new username:centos
  
centos exists.
  
[root@centos bash]#
  练习5:判断给定的两个数值,孰大孰小;
[root@centos bash]# cat 5.sh  
#!/bin/bash
  
#
  
#read -p "plz input two integer:" -t 10 num1 num2
  

  
if [ $# -lt 2 ];then
  
  echo "your input parameters are less than 2.plz re-enter."
  
  exit 1
  
fi
  

  
if [[ $1 =~ ^[0-9]+$ ]]&&[[ $2 =~ ^[0-9]+$ ]];then
  
   if [ $1 -gt $2 ];then
  
     echo "the max number is $1."
  
     echo "the min number is $2."
  
   else
  
     echo "the max number is $2."
  
     echo "the min number is $1."
  
   fi
  
else
  
   echo "the number $1 or $2 is not a integer.at least have a string."
  
fi
  

  
[root@centos bash]# ./5.sh 3 2
  
the max number is 3.
  
the min number is 2.
  
[root@centos bash]# ./5.sh a 4
  
the number a or 4 is not a integer.at least have a string.
  
[root@centos bash]# ./5.sh 2
  
your input parameters are less than 2.plz re-enter.
  
[root@centos bash]# ./5.sh a
  
your input parameters are less than 2.plz re-enter.
  
[root@centos bash]#
  2、case
  简洁版多分支if语句,当if语句中有多个elif时可以使用case语句代替,语言更简洁容易理解。使用场景:判断某变量的值是否为多种情形中的一种时使用;
  格式:
case $VARIABLE in  
    PATTERN1)
  
    分支1
  
    ;;
  
    PATTERN2)
  
    分支2
  
    ;;
  
    PATTERN3)
  
    分支3
  
    ;;
  
    ...
  
    *)
  
    分支n
  
    ;;
  
esac
  PATTERN可使用glob模式的通配符:
  *: 任意长度的任意字符;
  ?: 任意单个字符;
  []: 指定范围内的任意单个字符;
  a|b: 多选1;
  练习6:脚本可接受四个参数
  start: 创建文件/var/lock/subsys/SCRIPT_NAME
  stop: 删除此文件
  restart: 删除此文件并重新创建
  status: 如果文件存在,显示为"running",否则,显示为"stopped"
#!/bin/bash  
file_name=$(basename $0)
  
pfile="/data/test/$file_name"
  

  
if [ $# -lt 1 ];then
  
  echo "Usage: $0 start|stop|restart|status."
  
fi
  

  
case $1 in
  
  start)
  
    touch $pfile
  
    if [ -f $pfile ];then
  
      echo "$file_name was started."
  
    else
  
      echo "$file_name start failed."
  
    fi
  
    ;;
  
  stop)
  
    rm -f $pfile
  
    if [ -f $pfile ];then
  
     echo "$file_name stop failed."
  
    else
  
     echo "$file_name was stoped."
  
    fi
  
    ;;
  
  restart)
  
    if ! [ -f $pfile ];then
  
     echo "$file_name is not running."
  
    else
  
      rm -f $pfile
  
      if [ -f $pfile ];then
  
       echo "$file_name restart failed."
  
      else
  
       touch $pfile
  
       if [ -f $pfile ];then
  
        echo "$file_name was restarted."
  
       else
  
        echo "$file_name restart failed."
  
       fi
  
      fi
  
    fi
  
    ;;
  
  status)
  
    if [ -f $pfile ];then
  
      echo "$file_name is running."
  
    else
  
      echo "$file_name is stop."
  
    fi
  
    ;;
  
  *)
  
   echo "Usage: $0 start|stop|restart|status."
  
   ;;
  
esac
  二、循环语句
  1、for……do……done
  格式:
  (1)、for CONDITION;do
  doing-loop
  done
  condition是决定for循环的次数,运行和退出循环的条件。他的形式有多种样式,下面是列举的几种类型:
  1、List:可以罗列出变量具体的取值范围,枚举。例:
  name  in user1,user2,user3,user4
  2、命令引用:如果是连续的数字可以引用命令seq,这里也可以是其他能够取出一组数据的命令。例:
  i  in `seq 1 100`
  整数数字还可以写成{1...100},与seq命令效果相同。
  3、还可以是已经定义好的数组,例:
  a=(1,3,4,5,6,7)
  i in ${a
  • }
      4、或者取某一范围的值,例:
      file in /var/log/*
      练习7:求100以内所有偶数之和;
    [root@centos bash]# ./6.sh  
    2550
      
    [root@centos bash]# cat 6.sh
      
    #!/bin/bash
      
    declare -i sum
      
    for i in `seq 0 2 100`;do
      
      sum+=$i
      
    done
      
    echo $sum
      
    [root@centos bash]#
    [root@centos bash]# cat 6.sh  
    #!/bin/bash
      
    declare -i sum
      
    for i in {1..100};do
      
      if [ $[$i%2] -eq 0 ];then
      
        sum+=$i
      
      fi
      
    done
      

      
    echo $sum
      
    [root@centos bash]# ./6.sh
      
    2550
      
    [root@centos bash]#
      练习8:显示/etc目录下所有普通文件列表,而后统计一共有多少个文件
    [root@centos bash]# cat 7.sh  
    #!/bin/bash
      
    declare -i conut=0
      
    for file in /etc/*;do
      
       if [ -f $file ];then
      
    let conut++
      
            echo $conut $file
      
       fi
      
    done
      
    [root@centos bash]# ./7.sh
      
    1 /etc/adjtime
      
    2 /etc/aliases
      
    ……
      
    124 /etc/wgetrc
      
    125 /etc/yp.conf
      
    126 /etc/yum.conf
      
    [root@centos bash]#
      练习9:写一个脚本
      (1) 传递两个文本文件路径给脚本;
      (2) 显示两个文件中空白行数较多的文件及其空白行的个数;
      (3) 显示两个文件中总行数较多的文件及其总行数;
    [root@centos bash]# cat 8f.sh  
    #!/bin/bash
      
    space_lines1=$[$(grep '^$' $1|wc -l)+$(grep '^[[:space:]]\+$' $1|wc -l)]
      
    space_lines2=$[$(grep '^$' $2|wc -l)+$(grep '^[[:space:]]\+$' $2|wc -l)]
      

      
    if [ $space_lines1 -gt $space_lines2 ];then
      
       echo "File $1 have $space_lines1 space lines more than $2."
      
    else
      
       echo "File $2 have $space_lines2 space lines more than $1."
      
    fi
      
    ###############################################################################
      
    file_lines1=$(cat $1|wc -l)
      
    file_lines2=$(cat $2|wc -l)
      
    if [ $file_lines1 -gt $file_lines2 ];then
      
        echo "File $1 have $file_lines1 lines more than $2."
      
    else
      
        echo "File $2 have $file_lines2 lines more than $1."
      
    fi
      

      
    [root@centos bash]# ./8f.sh 5.sh 6.sh
      
    File 5.sh have 3 space lines more than 6.sh.
      
    File 5.sh have 21 lines more than 6.sh.
      
    [root@centos bash]#
      练习10:写一个脚本,打印九九乘法表;
    [root@centos bash]# cat 9.sh  
    #!/bin/bash
      
    for i in {1..9};do
      
      for j in $(seq 1 $i);do
      
        if ! [ $i -eq $j ];then
      
           echo -n -e "${j}X${i}=$[$i*$j]\t"
      
        else
      
           echo -e "${j}x${i}=$[$i*$j]\t"
      
        fi
      
      done
      
    done
      
    [root@centos bash]# ./9.sh
      
    1x1=1
      
    1X2=2 2x2=4
      
    1X3=3 2X3=6 3x3=9
      
    1X4=4 2X4=8 3X4=12 4x4=16
      
    1X5=5 2X5=10 3X5=15 4X5=20 5x5=25
      
    1X6=6 2X6=12 3X6=18 4X6=24 5X6=30 6x6=36
      
    1X7=7 2X7=14 3X7=21 4X7=28 5X7=35 6X7=42 7x7=49
      
    1X8=8 2X8=16 3X8=24 4X8=32 5X8=40 6X8=48 7X8=56 8x8=64
      
    1X9=9 2X9=18 3X9=27 4X9=36 5X9=45 6X9=54 7X9=63 8X9=72 9x9=81
      
    [root@centos bash]#
      
    简化
      
    #!/bin/bash
      
    for i in {1..9};do
      
      for j in $(seq 1 $i);do
      
           echo -n -e "${j}X${i}=$[$i*$j]\t"
      
      done
      
        echo
      
    done
      2、while/do……while
      格式:
      while CONDITION; do
      循环体
      控制变量的修正表达式
      done
      进入条件:当CONDITION为“真”;
      退出条件:当CONDITION为“假”;
      练习11:分别求100以内所有奇数之和,及所有偶数之和
    [root@centos bash]# cat 11.sh  
    #!/bin/bash
      
    declare -i sum=0
      
    declare -i sum_1=0
      
    declare -i sum_2=0
      
    declare -i i=1
      
    while [ $i -le 100 ];do
      
      if [ $[$i%2] -eq 0 ];then
      
        sum_1+=$i
      
      else
      
        sum_2+=$i
      
      fi
      
       sum+=$i
      
       let i++
      
    done
      
      echo "the sum of numbers in 100 is $sum."
      
      echo "the sum of odd numbers in 100 is $sum_1."
      
      echo "the sum of even numbers in 100 is $sum_2."
      3、Until
      格式:
      until CONDITION; do
      循环体
      循环控制变量的修正表达式
      done
      进入条件:当CONDITION为“假”时
      退出条件:当CONDITION为“真”时
      练习12:分别使用while和until循环实现添加10个用户:user1-user10
    [root@centos bash]# cat 12.sh  
    #!/bin/bash
      
    declare -i i=1
      
    until [ $i -eq 11 ];do
      
      useradd user$i
      
      let i++
      
    done
      
    [root@centos bash]# tail /etc/passwd
      
    haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
      
    gdm:x:42:42::/var/lib/gdm:/sbin/nologin
      
    ntp:x:38:38::/etc/ntp:/sbin/nologin
      
    apache:x:48:48:Apache:/var/www:/sbin/nologin
      
    saslauth:x:498:76:Saslauthd user:/var/empty/saslauth:/sbin/nologin
      
    postfix:x:89:89::/var/spool/postfix:/sbin/nologin
      
    pulse:x:497:496:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
      
    sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
      
    tcpdump:x:72:72::/:/sbin/nologin
      
    centos:x:500:500::/home/centos:/bin/bash
      
    [root@centos bash]# chmod +x 12.sh
      
    [root@centos bash]# ./12.sh
      
    [root@centos bash]# tail /etc/passwd
      
    user1:x:501:501::/home/user1:/bin/bash
      
    user2:x:502:502::/home/user2:/bin/bash
      
    user3:x:503:503::/home/user3:/bin/bash
      
    user4:x:504:504::/home/user4:/bin/bash
      
    user5:x:505:505::/home/user5:/bin/bash
      
    user6:x:506:506::/home/user6:/bin/bash
      
    user7:x:507:507::/home/user7:/bin/bash
      
    user8:x:508:508::/home/user8:/bin/bash
      
    user9:x:509:509::/home/user9:/bin/bash
      
    user10:x:510:510::/home/user10:/bin/bash
      
    [root@centos bash]#
      4、循环控制:
      continue [n]:提前结束本轮循环,而直接进入下一轮;
      break [n]:提前结束循环;
      5、死循环:
      始终满足执行条件,无法退出循环。这样的循环内,可以使用循环控制来跳出循环。
      格式:
      (1)while true; do
      循环体
      done
      (2)until false; do
      循环体
      done
      6、特殊的循环用法:
      (1)while遍历文件的每一行
      while read VARIABLE; do
      循环体
      done < /PATH/FROM/SOME_FILE
      (2)For循环类C++用法
      for ((expr1;expr2;expr3)); do
      循环体
      done
      练习13:传递一个文本文件为参数给脚本,取出此文件的所有的偶数行给予显示,行前要显示行号;
    [root@centos bash]# cat 13.sh  
    #!/bin/bash
      
    grep -n '.' $1|cut -d: -f1|while read line_nu;do
      
       line=`sed -n "${line_nu}p" $1`
      
       if [ $[$line_nu%2] -eq 0 ];then
      
       echo $line_nu $line
      
       fi
      
    done
      
    [root@centos bash]# ./13.sh 12.sh
      
    2 declare -i i=1
      
    4 useradd user$i
      
    6 done
      
    [root@centos bash]#
      三、函数
      把一段具有独立功能代码封装在一起,并给予命名;后续用到时,可直接通过给定函数名来调用整体代码;
      函数作用:1、代码重用;2、模块化编程
      函数的使用方法:
      先定义:编写函数代码
      后调用:给出函数名,还可按需传递参数
      定义方法:
      (1) function f_name {
      函数体
      }
      (2) f_name() {
      函数体
      }
      调用函数:
      f_name [argu1, argu2, ...]
      自定义函数状态返回值:
      return [#]
      0: 成功
      1-255:失败
      注意:函数代码执行时,一旦遇到return,函数代码终止运行,函数返回;



  • 运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
    2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
    3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
    4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
    5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
    6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
    7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
    8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

    所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-557860-1-1.html 上篇帖子: [9-13]Shell系列6——取算数运算数值 下篇帖子: bash shell基础之二条件判断
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    扫码加入运维网微信交流群X

    扫码加入运维网微信交流群

    扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

    扫描微信二维码查看详情

    客服E-mail:kefu@iyunv.com 客服QQ:1061981298


    QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


    提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


    本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



    合作伙伴: 青云cloud

    快速回复 返回顶部 返回列表