• Shell-条件控制语句2


    案例: 写一个脚本传参的方式做一个计算器 加减乘除
        [root@test day3]# cat count.sh 
        #!/bin/bash
        expr $1 + $2 &>/dev/null
        [ $? -ne 0 ] && exit
        echo $1+$2=$[$1+$2]
        echo $1-$2=$[$1-$2]
        echo $1*$2=$[$1*$2]
        echo $1/$2=$[$1/$2]
        num1=$1
        num2=$2
        echo $num1/$num2=$[$num1/$num2]
        echo $num1+$num2=$[$num1+$num2]
        echo $num1-$num2=$[$num1-$num2]
        echo $num1*$num2=$[$num1*$num2]

        read -p "Please Input two Number: " num1 num2
        echo $num1/$num2=$[$num1/$num2]
        echo $num1+$num2=$[$num1+$num2]
        echo $num1-$num2=$[$num1-$num2]
        echo $num1*$num2=$[$num1*$num2]

    案例: 使用read传参 输入两个整数 是否为整数做判断 然后比对两个数字的大小(禁止使用if)
    注意正则表达式: 并且&& 或者||

    [root@test day3]# cat diff.sh 
    #!/bin/bash
    read -p "Please input two number: " num1 num2
    if [[  $num1 =~ ^[0-9]+$ && $num2 =~ ^[0-9]+$ ]];then
        [ $num1 -gt $num2 ] && echo "$num1>$num2"
        [ $num1 -lt $num2 ] && echo "$num1<$num2"
        [ $num1 -eq $num2 ] && echo "$num1=$num2"
    else
        exit
    fi

    案例: 
    1. 获取磁盘使用率
    2. 获取到的值如果大于80则发送邮件告警 小于80则提示磁盘使用率正常 并输出当前的值
        [root@test day3]# cat disk.sh
        #!/bin/bash
        . /etc/init.d/functions
        use_disk=`df -h|awk '/\/$/{print $(NF-1)}'`
        if [ ${use_disk%\%} -gt 15 ];then
           action "磁盘使用不正常" /bin/false
        else
            action "磁盘使用正常: $use_disk" /bin/true
        fi
        [root@test day3]# sh disk.sh
        磁盘使用正常: 11%                                          [  OK  ]

    1. 获取内存使用率
    2. 如果内存值大于80则提示内存使用异常输出当前值 小于80则提示内存使用正常 输出当前值

        [root@test day3]# cat free.sh
        #!/bin/bash
        . /etc/init.d/functions
        use_free=`free|awk 'NR==2{print $3/$2*100}'`
        if [ ${use_free%.*} -lt 10 ];then
           action "内存使用不正常: $use_free" /bin/false
        else
            action "内存使用正常: $use_free" /bin/true
        fi
        [root@test day3]# sh free.sh
        内存使用正常: 11.8201                                      [  OK  ]
        [root@test day3]# vim free.sh 
        [root@test day3]# sh free.sh 
        内存使用不正常: 11.8186                                    [FAILED]


    1. 获取Linux操作系统的以下信息 输出到屏幕:
      ETH0ip地址
      公网IP地址
      系统版本
      虚拟平台Virtualization
      内核版本
      主机名称
      磁盘使用率
      内存使用率
      负载
      网络是否正常
      
       [root@test day3]# cat test.sh 
        #!/bin/bash
        [ -f /etc/init.d/functions ] && source /etc/init.d/functions
        fidsk=`df -h | grep 11|awk '{print $(NF-1)}'|grep 11 -o`
         [ $fidsk -ge 80  ] && mail -s '磁盘报警' 798924094@qq.com < /server/scripts/fidsk.txt&>/dev/null || action "磁盘使用率" /bin/true 
        sleep 0.5
        eth0=`ifconfig eth0|awk -F: NR==1'{print $1}'`
        if [ $eth0 = $eth0 ];then
          action "IP地址是: $eth0:$IP" /bin/true 
        else
          action "IP地址是: $eth0:$IP" /bin/false
        fi
        sleep 0.5
        gwIP=`curl -s cip.cc|grep ^IP |awk '{print $3}'`
        if [ $gwIP = $gwIP ];then
          action "公网IP地址: $gwIP" /bin/true
        else 
          action "公网IP地址: $gwIP" /bin/false 
        fi
        sleep 0.5
        xtbb=`hostnamectl|grep Cen|awk '{print $3,$4,$5}'`
        if [ xtbb = xtbb ];then
          action  "系统版本为: $xtbb"  /bin/true
        else
          action  "系统版本为: $xtbb" /bin/false
        fi
        sleep 0.5
        xuni=`hostnamectl|grep vmwar|awk '{print $2}'`
        if [ $xuni = $xuni ];then
          action "虚拟平台为: $xuni"   /bin/true
        else
          action  "虚拟平台为: $xuni"  /bin/false
        fi
        sleep 0.5
        shuzi=`hostnamectl|grep x86-64|awk '{print $2}'`
        if [ $shuzi = $shuzi ];then
          action   "内核版本为: $shuzi"  /bin/true
        else
          action   "内核版本为: $shuzi" /bin/false
        fi
        sleep 0.5
        name=`hostname`
        if [ $name = $name ];then
          action   "主机名为: $name"  /bin/true
        else
          action   "主机名为: $name"  /bin/false
        fi
        sleep 0.5
        free=`free -h|awk NR==2'{print $3/$2*100}'|awk -F [.4]+ '{print $1}'`
        if [ $free -ge 80  ];then
          mail -s "内存溢出" 798924094@qq.com < 内存溢出超过80
        else
          action "内存的使用率为: $free"  /bin/true
        fi
        sleep 0.5
        uptime=`uptime|awk -F "[ ,]+" '{print $(NF-2)}'|awk -F. '{print $1}'`
        if [ $uptime -ge 60 ];then
           mail -s "内存溢出" 798924094@qq.com < 内存溢出超过80
        else
          action "负载状态: $uptime"  /bin/true
        fi
        sleep 0.5
        ping -c1 -W1 www.baidu.com &>/dev/null
        if [ $? -eq 0 ];then
           action "网络情况" /bin/true
        else
           action "网络情况" /bin/false
        fi
         
      
      
      
      
      
      
      
      
      
      
      
      
    一.if判断  
    语法结构:
    单分支语句: 一个条件 一个结果
    第一种写法: then在表达的后面 加个分号;
    if 条件表达式;then
       执行的命令集合
    fi
    第二种写法: then在if的下面条件表达式的后面不需要加分号;
    if 条件表达式
    then
        执行命令
    fi

    if [ 20 -eq 20 ]
    then 
        echo ok
    fi

    if [ -f /etc/hosts ];then
       echo 文件存在
    fi

    if [[ root =~ ^r ]]
    then 
        echo ok
    fi


    if的单分支和&& 相同 
    一个条件 一个结果

    [root@test day3]# [ 10 -eq 10 ] && echo ok
    ok
    [root@test day3]# [ 10 -eq 11 ] && echo ok

    [root@test day3]# cat if.sh
    if [ 10 -eq 10 ]
    then
        echo ok
    fi


    单条件
    if  [ 你有房 ]
    then
        我就嫁给你
    fi 

    双分支 一个条件 两个结果
    if [ 你有房 ]
    then 
        我就嫁给你
    else
        拜拜
    fi

    [ 10 -eq 10 ] && echo 成立 || echo 不成立 

    多分支 多个条件 多个结果
    if [ 你有房 ]
    then 
        我就嫁给你 
    elif [ 你有钱 ]
    then
        我也嫁给你
    elif [ 你活好 ] Linux学的好
    then
        先处对象
    else
        拜拜
    fi


    案例: 根据不同的操作系统版本安装不同的YUM源
    1. 获取操作系统版本号
    2. 通过表达判断
    3. 部署YUM仓库
    -------------------------- 框架
    [root@test day3]# cat if.sh
    #!/bin/bash
    #获取操作系统版本号
    os_vs=`awk '{print $(NF-1)}' /etc/redhat-release`
    if [ ${os_vs%%.*} -eq 7 ]
    then
        # 备份默认YUM仓库
        mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
        # 下载新的YUM仓库
        wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
    elif [ ${os_vs%%.*} -eq 6 ]
    then
        # 备份默认YUM仓库
        mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
        # 下载新的YUM仓库
        wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-6.10.repo
    elif [ ${os_vs%%.*} -eq 8 ]
    then
        # 备份默认YUM仓库
        mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
        # 下载新的YUM仓库 
        wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo
    fi
    ----------------------------------------

    完善脚本:
    [root@test day3]# cat if.sh 
    #!/bin/bash
    #获取操作系统版本号
    # 调用系统函数库
    [ -f /etc/init.d/functions ] && . /etc/init.d/functions

    os_vs=`awk '{print $(NF-1)}' /etc/redhat-release`
    backup_yum='mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup'

    # 判断网络
    ping -c1 -W1 www.baidu.com &>/dev/null
    if [ $? -ne 0 ]
    then
        systemctl restart network
        if [ $? -eq 0 ];then
            action "重启网卡成功" /bin/true
        else
            action "网卡重启失败请手动检查配置" /bin/false
        fi
        ping -c1 -W1 www.baidu.com &>/dev/null
        [ $? -ne 0 ] && action "请管理手动检查网络" /bin/false
    fi

    # 判断wget是否存在 不存在则安装
    which wget &>/dev/null
    if [ $? -ne 0 ]
    then
        echo "正在安装wget请稍等........"
        yum -y install wget &>/dev/null
        if [ $? -eq 0 ];then
        action "wget install is " /bin/true
        else
        action "wget install is" /bin/false
        echo "正在安装wget安装成功继续执行脚本.."
        fi
    fi

    if [ ${os_vs%%.*} -eq 7 ]
    then
        # 备份默认YUM仓库
        $backup_yum
        # 下载新的YUM仓库
        wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo &>/dev/null
        if [ $? -eq 0 ];then
        action "yum仓库安装" /bin/true
        else
        action "yum仓库安装" /bin/false
        fi

    elif [ ${os_vs%%.*} -eq 6 ]
    then
        # 备份默认YUM仓库
        $backup_yum
        # 下载新的YUM仓库
        wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-6.10.repo
    elif [ ${os_vs%%.*} -eq 8 ]
    then
        # 备份默认YUM仓库
        $backup_yum
        # 下载新的YUM仓库 
        wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo
    fi
    --------------------------------------------------------------

    案例: 输入两个整数判断比较两个数大小
    [root@test day3]# cat num.sh 
    #!/bin/sh
    read -p "Please Input two Number: " num1 num2
    if [[ ! $num1 =~ ^[0-9]+$ || ! $num2 =~ ^[0-9]+$ ]];then
       echo "请输入整数"
       exit
    fi
    if [ $num1 -gt $num2 ]
    then
        echo "$num1 > $num2"
    elif [ $num1 -lt $num2 ]
    then
        echo "$num1 < $num2"
    else
        echo "$num1 = $num2"
    fi


    案例: if菜单
    打印输出菜单 安装多个不同的版本
    [root@test day3]# cat server.sh 
    #!/bin/sh
    echo -e "\t\t\t\t\t \033[40;32m 1.PHP \033[0m"
    echo -e "\t\t\t\t\t \033[40;32m 2.Redis \033[0m"
    echo -e "\t\t\t\t\t \033[40;32m 3.MySQL \033[0m"
    echo -e "\t\t\t\t\t \033[40;32m 4.Nginx \033[0m"
    cat<          1.PHP
             2.Redis
             3.MySQL
             4.Nginx
    EOF

    二级菜单:
    [root@test day3]# cat server.sh 
    #!/bin/sh
    echo -e "\t\t\t\t\t \033[40;32m 1.PHP \033[0m"
    echo -e "\t\t\t\t\t \033[40;32m 2.Redis \033[0m"
    echo -e "\t\t\t\t\t \033[40;32m 3.MySQL \033[0m"
    echo -e "\t\t\t\t\t \033[40;32m 4.Nginx \033[0m"
    read -p "请输入你要安装的服务名称或者编号:[1|PHP|2|Redis|3|MySQL|4|Nginx] " num
    if [ $num = 1 -o $num = PHP ]
    then
            echo -e "\t\t\t\t\t \033[40;34m 1.PHP5.4 \033[0m"
        echo -e "\t\t\t\t\t \033[40;34m 2.PHP7.1 \033[0m"
        echo -e "\t\t\t\t\t \033[40;34m 3.PHP7.2 \033[0m"
        echo -e "\t\t\t\t\t \033[40;34m 4.PHP7.4 \033[0m"
            read -p "请选择你要安装的版本号:[1|2|3]" num
            if [ $num -eq 1 ];then
               echo "yum_install_php5.4............."
            elif [ $num -eq 2 ];then
               echo "yum_install_php7.1............."
        else
           echo "请按照菜单选择别瞎选!!!"
              exit
        fi

    elif [ $num = 2 -o $num = Redis ]
    then
            echo -e "\t\t\t\t\t \033[40;33m 1.Redis-1.6 \033[0m"
            echo -e "\t\t\t\t\t \033[40;33m 2.Redis-1.7 \033[0m"
            echo -e "\t\t\t\t\t \033[40;33m 3.Redis-1.8 \033[0m"
            echo -e "\t\t\t\t\t \033[40;33m 4.Redis-1.9 \033[0m"
                    read -p "请选择你要安装的版本号:[1|2|3]" num
            if [ $num -eq 1 ];then
               echo "yum_install_redis1.6............."
            elif [ $num -eq 2 ];then
               echo "yum_install_redis1.7............."
            fi
    else
       echo "请按照菜单选择别瞎选!!!"
       exit

    fi


    ------------------------------完善
    [root@test day3]# cat server.sh
    #!/bin/sh
    while true
    do
        echo -e "\t\t\t\t\t \033[40;32m 1.PHP \033[0m"
        echo -e "\t\t\t\t\t \033[40;32m 2.Redis \033[0m"
        echo -e "\t\t\t\t\t \033[40;32m 3.MySQL \033[0m"
        echo -e "\t\t\t\t\t \033[40;32m 4.Nginx \033[0m"
        echo -e "\t\t\t\t\t \033[40;32m 5.退出脚本 \033[0m"
        read -p "请输入你要安装的服务名称或者编号:[1|PHP|2|Redis|3|MySQL|4|Nginx] " num
        if [ $num = 1 -o $num = PHP ]
        then
            while true
             do
            echo -e "\t\t\t\t\t \033[40;34m 1.PHP5.4 \033[0m"
            echo -e "\t\t\t\t\t \033[40;34m 2.PHP7.1 \033[0m"
            echo -e "\t\t\t\t\t \033[40;34m 3.PHP7.2 \033[0m"
            echo -e "\t\t\t\t\t \033[40;34m 4.PHP7.4 \033[0m"
            echo -e "\t\t\t\t\t \033[40;34m 5.返回主菜单 \033[0m"
            read -p "请选择你要安装的版本号:[1|2|3]" num
            if [ $num -eq 1 ];then
               echo "yum_install_php5.4............."
            elif [ $num -eq 2 ];then
               echo "yum_install_php7.1............."
            elif [ $num -eq 5 ];then
                  break
            else
               echo "请按照菜单选择别瞎选!!!"
               exit
            fi
             done
        elif [ $num = 2 -o $num = Redis ]
        then
            echo -e "\t\t\t\t\t \033[40;33m 1.Redis-1.6 \033[0m"
            echo -e "\t\t\t\t\t \033[40;33m 2.Redis-1.7 \033[0m"
            echo -e "\t\t\t\t\t \033[40;33m 3.Redis-1.8 \033[0m"
            echo -e "\t\t\t\t\t \033[40;33m 4.Redis-1.9 \033[0m"
                read -p "请选择你要安装的版本号:[1|2|3]" num
            if [ $num -eq 1 ];then
               echo "yum_install_redis1.6............."
            elif [ $num -eq 2 ];then
               echo "yum_install_redis1.7............."
            fi
        elif [ $num = 5 ]
            then
             exit
        else
           echo "请按照菜单选择别瞎选!!!"
           echo "请重新输入编号"

            fi


    done
    ----------------------------------------------------------------------------


    案例: 
    猜数字游戏
    1.生成一个随机数
    2.让用户输入数字
    3.猜大小  大了提示大了 小则提示小了 输入正确则提示恭喜猜对了

    $RANDOM 数字范围: 0-32767

    echo $((RANDOM%100+1)) 1-100的数字

    [root@test day3]# cat ran.sh 
    #!/bin/bash
    ran=`echo $((RANDOM%100+1))`

    while true
    do
        let i++
        read -p "请你输入要猜的数字[1-100]: " num
        if [ $num -gt $ran ]
        then
           echo "你输入数字的大了"
        elif [ $num -lt $ran ]
        then
           echo "你输入数字的小了"
        else
             echo "恭喜你猜对了中奖号码是: $ran"
             echo "总共猜了$i 次"
             exit
        fi
    done

    作业: 
    系统自动猜 并且统计猜的数字
    系统猜过的数字放入一个文本
    然后过滤统计判断 如果有则重复赋值
    (重复赋值)

    [root@test day3]# cat test.sh
    #!/bin/bash
    > 1.txt
    num=`echo $((RANDOM%100+1))`
    while true
    do
                while true
            do
            ran=`echo $((RANDOM%100+1))`
            if [ `grep -w $ran 1.txt|wc -l` -eq 1  ];then
                    continue
                else
                   let i++
               echo $ran >> 1.txt
               break
                fi
            done
            if [ $num -eq $ran ];then
               echo "恭喜系统猜对了$i 次"
               exit
            fi

    done


    双色球
    6红+1个篮球  共7个号码
    6红数字范围: 1-33
    1个篮球:     1-16

    ran1=`echo $((RANDOM%100+1))`
    ran2=`echo $((RANDOM%100+1))`
    ran3=`echo $((RANDOM%100+1))`

    当前1-33里的数字被赋值 不能在给其他变量赋值

    二.for循环
    for 变量名称 in  取值列表
    do
        动作
    done

    取值列表: 数字 字符串 命令 序列 以空格为分隔符

        循环数字:
        [root@test day3]# cat for.sh
        #!/bin/bash
        for i in 1 2 3 4 5
        do
            echo $i
        done
        [root@test day3]# sh for.sh
        1
        2
        3
        4
        5

    循环字符串
        [root@test day3]# cat for.sh
        #!/bin/bash
        for i in oldboy test1 lidao
        do
            echo $i
        done
        [root@test day3]# sh for.sh
        oldboy
        test1
        lidao

    值的列表可以使用双引号引用
        [root@test day3]# cat for.sh
        #!/bin/bash
        for i in "oldboy test1" lidao
        do
            echo $i
        done
        [root@test day3]# sh for.sh
        oldboy test1
        lidao

    注意: 输出的结果可以和for循环的列表没有任何关系 和循环次数有关 赋值几次则动作执行几次
        [root@test day3]# cat for.sh
        #!/bin/bash
        for i in a b c
        do
            echo ok
        done
        [root@test day3]# sh for.sh
        ok
        ok
        ok
    统计循环或者赋值次数
        [root@test day3]# cat for.sh
        #!/bin/bash
        for i in a b c
        do
            let a++
        done
        echo $a
        [root@test day3]# sh for.sh
        3

    for循环读取文件
        [root@test day3]# cat /etc/hosts
        127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
        ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
        [root@test day3]# cat for.sh 
        #!/bin/bash
        for i in `cat /etc/hosts`
        do
            echo $i
        done
        [root@test day3]# sh for.sh 
        127.0.0.1
        localhost
        localhost.localdomain
        localhost4
        localhost4.localdomain4
        ::1
        localhost
        localhost.localdomain
        localhost6
        localhost6.localdomain6

    for循环支持序列
        [root@test day3]# cat for.sh
        #!/bin/bash
        for i in {a..c}
        do
            echo $i
        done
        [root@test day3]# sh for.sh
        a
        b
        c


        [root@test day3]# cat for.sh
        #!/bin/bash
        for i in {1..10}
        do
            echo $i
        done
        [root@test day3]# sh for.sh
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10


        [root@test day3]# cat for.sh
        #!/bin/bash
        for i in `seq 10`
        do
            echo $i
        done

    案例1: 测试一个网段内的IP地址是否在线  笔试题
           ping通则为在线
           
           [root@test day3]# cat for.sh 
            #!/bin/bash
            for i in {1..10}
            do
               {
                ip=10.0.0.$i
                ping -c1 -W1 $ip &>/dev/null
                if [ $? -eq 0 ]
                then
                    echo "$ip 在线"
                fi
                } &
            done
            wait   # 等待后台程序执行完毕后继续往下执行
            echo done..................

    案例2: 批量创建用户  每个用户8位随机密码 并且保存用户名对应密码关系表
           要求用户输入前缀 用户输入个数test01..test10
           
        [root@test day3]# cat user.sh 
        #!/bin/bash
        read -p "请输入用户名称的前缀: " prefix
        read -p "请输入要创建用户的个数: " num
        for i in `seq $num`
        do
            echo ${prefix}$i
        done
        read -p "删除还是创建以上用户[y|n]" re
        if [ $re = y ]
        then
            for a in `seq $num`
            do
               user=${prefix}$a
               id $user &>/dev/null
               if [ $? -ne 0 ];then
                  useradd $user
                  if [ $? -eq 0 ];then
                 echo "$user 创建成功"
              fi
               else
                  echo "useradd: user $user 已存在"
               fi
            done  
        elif [ $re = n ]
        then
           for b  in `seq $num`
           do
               user=${prefix}$b
               id $user &>/dev/null
               if [ $? -eq 0 ];then
                  userdel -r $user
                  [ $? -eq 0 ] && echo "$user 删除成功"
               else
                  echo "$user 不存在"
               fi
           done

        fi


    案例3: for循环从1加到100 笔试题
    [root@test day3]# cat for1.sh 
    #!/bin/bash
    for i in {1..100}
    do
         count=$[$count+$i]
    done
    echo $count
    [root@test day3]# cat for1.sh
    #!/bin/bash
    for i in {1..100}
    do
         count=$[count+i]        # 此处括号中可以不加$
    done
    echo $count

    [root@test day3]# seq -s + 100|bc
    5050


    案例4:反向破解随机数的MD5值

    [root@test day3]# cat for2.sh 
    num1=31d30eea8d0968d6458e0ad0027c9f80
    for i in `seq 15`
    do
             ran=`echo ${i}|md5sum|awk '{print $1}'`
             if [ $num1 = $ran ]
             then
                 echo "$i $ran"
         fi
    done
    [root@test day3]# sh for2.sh
    10 31d30eea8d0968d6458e0ad0027c9f80

    ----------------破解出对应的数字
    4f9f2d27
    091ba725
    acf6c3a0
    f3f5799e
    1fe0fee
    a4954ca
    --------------------------------

    作业: 编写吃饭脚本
    1. 菜单
       快餐
       炒菜
       驴肉火烧
       王八
       ...
       ...
    2. 按键随机选择中午晚上吃啥

    1.菜单 价格
    2.会员卡 直接消费 (加会员卡密码) 预留邮箱 找回密码
    3.没有会员 是否办理 办理是否有有优惠冲1000送亿万 数值写入文件中 会员姓名: 存储余额
    4.消费点菜
    5.结账会员结账 处理文本
    6.将余额发送企业微信

    一. while循环
    语法结构:
    # 当前条件表达式成立(为真)则执行do后面的命令
    while [ 条件表达式 ]
    do
         命令的集合
    done 

    案例: 笔试题 写一个死循环脚本
        [root@test day3]# cat while.sh 
        while true
        do
              echo test
              sleep 2
        done

        [root@test day3]# cat while.sh 
        while [ 10 -gt 5 ]
        do
              echo test
              sleep 2
        done


        [root@test day3]# cat while.sh
        while [ -f /etc/hosts ]
        do
              echo test
              sleep 2
        done

    while数字循环
        [root@test day4]# cat while.sh
        i=1
        while [ $i -le 10 ]
        do
              echo $i
              let i++
        done
        [root@test day4]# sh while.sh
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10

    案例: while从1加到100
        [root@test day4]# cat while.sh 
        i=1
        while [ $i -le 100 ]
        do
              count=$[count+i]
              let i++
        done
        echo $count
        [root@test day4]# sh while.sh 
        5050

    案例: while读取文件
    for循环读取文件按照空格分割 while循环按照行分隔
        [root@test day4]# cat read.sh
        #!/bin/bash
        while read line
        do
             echo $line
        done     [root@test day4]# sh read.sh
        127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
        ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6


    案例: while创建用户

    使用for循环(命令行行执行)
        [root@test day4]# for i in 取值列表; do 执行的命令;done
        [root@test day4]# for i in `cat user.txt`;do echo $i;done
        aa
        qq
        bb
        cc

        [root@test day4]# for i in `cat user.txt`;do useradd $i;done
        [root@test day4]# tail -4 /etc/passwd
        aa:x:1000:1000::/home/aa:/bin/bash
        qq:x:1001:1001::/home/qq:/bin/bash
        bb:x:1002:1002::/home/bb:/bin/bash
        cc:x:1003:1003::/home/cc:/bin/bash

    for循环删除用户
        [root@test day4]# for i in `cat user.txt`;do userdel -r $i;done

    使用while循环批量创建用户
        [root@test day4]# cat user.sh
        #!/bin/bash
        while read line
        do
              useradd $line
        done< user.txt
        [root@test day4]# sh user.sh
        [root@test day4]# tail -4 /etc/passwd
        aa:x:1000:1000::/home/aa:/bin/bash
        qq:x:1001:1001::/home/qq:/bin/bash
        bb:x:1002:1002::/home/bb:/bin/bash
        cc:x:1003:1003::/home/cc:/bin/bash


    通过用户传参的方式批量创建用户
    [root@test day4]# cat user.sh
    #!/bin/bash
    read -p "请输入用户的前缀名称: " pre 
    read -p "请输入创建用户的个数: " num
    i=1
    while [ $i -le $num ] 
    do
          user=${pre}$i
          id $user &>/dev/null
          re=$?
          if [ $re -ne 0 ];then
             useradd $user
             [ $? -eq 0 ] && echo "$user 创建成功"
          elif [ $re -eq 0 ]
             echo "$user 已经存在"
          fi  
          let i++
    done


    案例: while多级跳
    三层循环:
    [root@test day4]# cat while1.sh 
    #!/bin/bash
    while true
    do
             echo "第一级"
             sleep 1
             while true
         do
             echo "第二级"
             sleep 1

             while true
             do
               echo "第三级"
               sleep 1
             done

         done
    done
    echo done....................

    break跳出循环

    [root@test day4]# cat while1.sh 
    #!/bin/bash
    while true
    do
             echo "第一级"
             sleep 1
             while true
         do
             echo "第二级"
             sleep 1

             while true
             do
               echo "第三级"
               sleep 1
               break 3
             done

         done
    done
    echo done....................


    exit 退出整个脚本

    continue 忽略剩余代码从头继续执行
        [root@test day4]# cat while1.sh 
        #!/bin/bash
        while true
        do
                 echo "第一级"
                 sleep 1
                 while true
             do
                 echo "第二级"
                 sleep 1
                 continue
                 while true
                 do
                   echo "第三级"
                   sleep 1
                 done

             done
        done
        echo done....................


    break 跳出循环体继续执行
        [root@test day4]# cat user.sh
        #!/bin/bash
        read -p "请输入用户的前缀名称: " pre 
        read -p "请输入创建用户的个数: " num
        i=1
        while [ $i -le $num ] 
        do
              user=${pre}$i
              id $user &>/dev/null
              if [ $? -ne 0 ];then
                 useradd $user
                 [ $? -eq 0 ] && echo "$user 创建成功"
              else
             break
              fi  
              let i++
        done
        echo done..............


    continue:
        [root@test day4]# cat user.sh 
        #!/bin/bash
        read -p "请输入用户的前缀名称: " pre 
        read -p "请输入创建用户的个数: " num
        i=0
        while [ $i -le $num ] 
        do
              let i++
              user=${pre}$i
              id $user &>/dev/null
              if [ $? -ne 0 ];then
                 useradd $user
                 [ $? -eq 0 ] && echo "$user 创建成功"
              else
                  continue
              fi  
        done
        echo done..............

    ---------------
        #!/bin/bash
        >test.txt
        while true
        do
              ran=`echo $((RANDOM%100+1))`
              if [ `grep -w $ran test.txt|wc -l` -eq 1 ];then
                 continue
              fi
              echo $ran >> test.txt
        done
    ----------------------


    二.函数
    函数的特点:
    1. 先定义在调用 如果只定义不调用则脚本不会执行(变量只定义不调用也会执行赋值)
    2. 函数为命令(代码)的集合(变量只能赋一个值 函数可以赋多个值)
    3. 可以重复调用

    调用脚本的变量
    [root@test day4]# cat 1.sh 
    name=oldboy
    [root@test day4]# cat 2.sh 
    . /server/scripts/day4/1.sh
    read -p "请输入你的年龄: " num
    echo 名字: $name 年龄: $num


    1.函数的定义
    [root@test day4]# cat fun.sh 
    #!/bin/bash
    fun1(){
         echo "第一种书写方式"
    }
    function fun2 {
         echo "第二种书写方式"
    }
    function fun3(){
         echo "第三种书写方式"
    }
    fun1            # 调用函数 直接在函数的下面写函数名称即可调用
    fun2
    fun3


    函数复用:
    [root@test day4]# source fun.sh 
    第一种书写方式
    第二种书写方式
    第三种书写方式
    [root@test day4]# fun1
    第一种书写方式
    [root@test day4]# fun2
    第二种书写方式
    [root@test day4]# fun3
    第三种书写方式

    2.函数的传参
    函数无法直接接收脚本的传参
    需要使用函数的传参方式进行传参
    直接在调用函数的后面进行传参
        [root@test day4]# cat fun.sh
        #!/bin/bash
        fun(){
             if [ -f $1 ]
             then
             echo "$1 文件存在"
             else
             echo "$1 文件不存在"
             fi
        }
        fun /etc/hosts /etc/passwd        # 在调用函数名称后面直接传参
        [root@test day4]# sh fun.sh
        /etc/hosts 文件存在
        [root@test day4]# sh -x fun.sh 
        + fun /etc/hosts /etc/passwd
        + '[' -f /etc/hosts ']'
        + echo '/etc/hosts 文件存在'
        /etc/hosts 文件存在


        [root@test day4]# cat fun.sh
        #!/bin/bash
        fun(){
             if [ -f $2 ]
             then
             echo "$2 文件存在"
             else
             echo "$2 文件不存在"
             fi
        }
        fun $2 $1
        [root@test day4]# sh fun.sh /etc/hosts /etc/passwd
        /etc/hosts 文件存在


    3.函数的变量
    函数中支持当前的全局变量
        [root@test day4]# cat fun.sh 
        #!/bin/bash
        file=/etc/hosts
        fun(){
             if [ -f $file ]
             then
             echo "$file 文件存在"
             else
             echo "$file 文件不存在"
             fi
        }
        fun


        [root@test day4]# cat fun.sh 
        #!/bin/bash
        num=2
        fun(){
             for i in `seq $num`
             do
             count=$[$count+$num]
             done 
             echo $count
        }
        fun

    定义函数的本地变量: 只在函数体内生效
        [root@test day4]# cat fun.sh 
        #!/bin/bash
        fun(){
             local num=20
             for i in `seq $num`
             do
             count=$[$1+$num]
             done 
             echo $count
        }
        fun 10
        echo $num


    4.函数的返回值
    通过exit返回状态码:
        [root@test day2]# cat env.sh 
        #!/bin/sh
        read -p "Please Input name env: " name
        [ -z $name ] && echo "必须输入名称" && exit
        if [[  $name =~ ^[a-Z]+$ ]];then
           echo $name
        else
           exit 100
        fi


        read -p "Please Input age env: " age
        if [[ $age =~ ^[0-9]{2}$ ]];then
          echo $age
        else
           exit 200
        fi
        echo $name $age


    通过赋值方式:
        [root@test day4]# cat fun.sh
        #!/bin/bash
        fun(){
             if [ -f $1 ]
             then
                 return 50
             else
                 return 100
             fi
        }
        fun $1
        re=$?
        if [ $re -eq 50 ]
        then
             echo "$1 文件存在"
        elif  [ $re -eq 100 ]
        then
             echo "$1 文件不存在"
        fi
        [root@test day4]# sh fun.sh /etc/passwd
        /etc/passwd 文件存在
        [root@test day4]# sh fun.sh /etc/passwdssss
        /etc/passwdssss 文件不存在


    案例: 重复判断
    ---------------
    # 判断下载YUM仓库是否成功的函数
    test_yum(){
        if [ $re -eq 0 ];then
        action "yum仓库安装" /bin/true
        else
        action "yum仓库安装" /bin/false
        fi
    }


    if [ ${os_vs%%.*} -eq 7 ]
    then
        # 备份默认YUM仓库
        $backup_yum
        # 下载新的YUM仓库
        wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo &>/dev/null
        #将执行的返回结果赋值给re
        re=$?
        #调用函数名称执行函数体中的命令
        test_yum

    elif [ ${os_vs%%.*} -eq 6 ]
    ------------------------------------------------------------------
        

    案例: 显示主菜单
    [root@test day4]# cat menu.sh 
    #!/bin/bash
    menu1(){
           echo "1.PHP"
              echo "2.MySQL"
              echo "h.显示主菜单"
    }
    menu1
    while true
    do
           read -p "请输入你要安装的服务编号: " num
               if [ $num = 1 ];then
                  while true
              do
                  echo "1.PHP1.1"
                  echo "2.PHP1.2"
                  echo "3.返回主菜单"
                  read -p "请输入安装的版本号: " re
                if [ $re -eq 1  ];then
                    echo yum php1.1.....
              elif [ $re -eq 3 ];then
                   break
              fi
               done
            elif [ $num = 2 ];then
              echo "1.MySQL1.1"
              echo "2.MySQL1.2"
           elif [ $num = h  ];then
               menu1
             fi

    done

    三. case
    语法结构:
    变量: 直接取值 read读入 赋值
    case 变量 in
              匹配模式1)
                  命令集合
              ;;
              匹配模式2)
                  命令集合
              ;;
              匹配模式3)
                  命令集合
              ;;
              *)
                  没有匹配到上面的模式 则执行 * 下的命令
    esac

    案例:
    [root@test day4]# cat case.sh 
    #!/bin/bash
    for i in `seq 10`
    do
       echo oldboy$i
    done
    read -p "选择删除或者创建以上用户:[y创建|d删除] " num

    case $num in
        y)
            for a in `seq 10`
            do
                   user=oldboy$a
                   id $user &>/dev/null
               if [ $? -eq 0 ];then
                   echo $user 用户存在
               else
                  useradd $user
                  [ $? -eq 0 ] && echo $user 创建成功
               fi

            done
        ;;
        d)
            for a in `seq 10`
                do
                       user=oldboy$a
                       id $user &>/dev/null
                       if [ $? -eq 0 ];then
                          userdel -r $user
                  [ $? -eq 0 ] && echo $user 删除成功
                       else
                          echo "$user 用户不存在"
                       fi

                done

            ;;
            *)
             echo "Usage: $0 [y|yes|d|del]"
    esac

    --------------------------------------for循环包含case语句
    [root@test day4]# cat case.sh 
    #!/bin/bash
    for i in `seq 10`
    do
       echo oldboy$i
    done

    read -p "选择删除或者创建以上用户:[y创建|d删除] " num

    for a in `seq 10`
    do
        case $num in
            y)
              user=oldboy$a
              id $user &>/dev/null
               if [ $? -eq 0 ];then
                  echo $user 用户存在
               else
                  useradd $user
                  [ $? -eq 0 ] && echo $user 创建成功
               fi

            ;;
            d)
                   user=oldboy$a
                   id $user &>/dev/null
                   if [ $? -eq 0 ];then
                      userdel -r $user
                      [ $? -eq 0 ] && echo $user 删除成功
                   else
                      echo "$user 用户不存在"
                   fi

            ;;
            *)
                 echo "Usage: $0 [y|yes|d|del]"
        esac
    done
    ---------------------------------------------------------------
    案例2:
         菜单:
              1.显示登录信息(执行w)
              2.显示内存
              3.显示磁盘
              4.显示IP地址
              5.显示外网IP地址
              6.显示主机名称
              7.显示菜单(可以先清屏在显示菜单)
    通过case语句执行 写入死循环


    [root@test day4]# cat os.sh 
    #!/bin/bash
    menu(){
        echo -e "\t\t\t\t\t\t1.f查看内存"
        echo -e "\t\t\t\t\t\t2.d查看磁盘"
        echo -e "\t\t\t\t\t\t3.u查看负载"
        echo -e "\t\t\t\t\t\t4.l查看登录信息"
        echo -e "\t\t\t\t\t\t5.c查看外网IP地址"
        echo -e "\t\t\t\t\t\t6.m显示菜单"
        echo -e "\t\t\t\t\t\t7.q退出脚本"
    }
    menu
    while true
    do
        read -p "请输入要查看的系统信息编号[1|f]: " num
        case $num in
              1|f)
               free -h
              ;;
              2|d)
               df -h
             ;;
              3|u)
               uptime
              ;;
              4|l)
               w
             ;;
              5|c)
               curl cip.cc
              ;;
             6|m)
                clear
                menu
              ;;
             7|q)
                  exit
              ;;
              *)
               echo "Usage: $0 [1|2|3|4|5|6]"
        esac
    done


    案例: 写一个服务的启动脚本
    Nginx启动脚本
    启动  /usr/sbin/nginx 
    停止 /usr/sbin/nginx -s stop
    重启 先停止后启动 /usr/sbin/nginx -s stop  && /usr/sbin/nginx
    重载  /usr/sbin/nginx -s reload
    状态 自定义

    [root@test day4]# cat nginx.sh 
    #!/bin/bash
    . /etc/init.d/functions
    re=$1
    fun(){
                  if [ $? -eq 0 ];then
                  action "Nginx $re is " /bin/true
                  else
                  action "Nginx $re is " /bin/false
                  fi
    }
    case $1 in
         start)
              /usr/sbin/nginx
               fun
         ;;
         stop)
              /usr/sbin/nginx -s stop
               fun
         ;;
         restart)
              /usr/sbin/nginx -s stop
              sleep 1
              /usr/sbin/nginx
               fun
          ;;
         reload)
              /usr/sbin/nginx -s reload
               fun
         ;;
         status)
              num=`ps axu|grep nginx|grep master|wc -l`
                if [ $num -eq 1 ];then
                 action "Nginx is running...."   /bin/true
              else
                 action "Nginx is down......."   /bin/false
              fi
          ;;
         *)
          echo "Usage: $0 [start|stop|restart|reload|status]"
    esac


    案例: 写一个跳板机
    要求:
    运维可以连接的主机和开发可以连接的主机不同
    1. 开发
    2. 运维
    开发
        > 开发菜单
    运维 
        > 运维菜单

    要求选择完输入密码才能进入菜单界面
    要求错误3次则等待10s

    又错3次 输入邮箱找回密码
            随机取8位数字发送到邮箱 将随机数保留
            用户复制邮箱内容和随机数做比较 如果正确提示用户输入新的密码
            用户名密码表格(输入邮箱直接将正确的密码发送到邮箱)
    ----------------------------------------------
    最外面死循环
    菜单:
    1. web01
    2. web02
    3. NFS
    4. MySQL

    选择要登录的主机使用case
    如果用户输入的是1)
                      ssh 10.0.0.7(提前做免秘钥)
    -------------------------------------------------                  
                      
     

  • 相关阅读:
    poetry日常开发使用
    原码反码补码移码的介绍和计算
    成都精灵云复试完结篇
    从新东方讲师到AI框架工程师,我的历次职业转折|OneFlow U
    【DevOps】Git 图文详解(三):常用的 Git GUI
    Node.js的POST请求与响应编程
    Node.js之ES6模块化及Promise对象
    Qt5在VS中调试时查看变量只能看到p,d指针的问题处理
    Docker部署Nginx+FastDFS插件
    德人合科技 | —数据泄露可能会对公司造成哪些影响?
  • 原文地址:https://blog.csdn.net/lpx1249115962/article/details/133213929