Shell编程

流程控制

1.基础知识

2.简单实践

3.小结

基础知识

编程逻辑

编程语言的目的是通过风格化的编程思路将代码写出来后,实现项目功能的。为了实现功能,我们通过在代码层面通过一些代码逻辑来实现:
    顺序执行 - 程序按从上到下顺序执行
    选择执行 - 程序执行过程中,根据条件选择不同的顺序执行
    循环执行 - 程序执行过程中,根据条件重复执行代码

shell逻辑

简介

    在shell编程中,默认情况下,处于shell脚本中的命令,它是按照从上到下的方式顺序执行每一条命令,这也导致我们在shell编程的过程中,必须保证每一条命令都能够正常的执行。当然了,真实的生产中的shell编程,不可能仅有这一种编程逻辑。
    许多程序在脚本命令之间需要某种逻辑流控制,这就意味着shell脚本在具体的场景中,根据条件判断选择一条具体的代码逻辑执行特定范围的命令 -- 脚本范围内,允许出现多个场景下的命令块,而控制执行不同命令块的编程逻辑结构,在shell编程中有一个名称 -- 结构化命令。

结构化命令

    结构化命令允许脚本程序根据条件或者相关命令的结果进行判断,执行一些功能命令块,在另外一些条件下,执行跳过这些命令块。
    在shell编程中,这些结构化的命令主要有:
条件逻辑 - 多分支执行命令块
    - if控制语句
    - case控制语句
    - select控制语句
循环逻辑 - 多循环执行命令块
    - for控制语句
    - while控制语句
    - until控制语句

if条件控制

语法解读

1.基础知识

2.简单实践

3.小结

基础知识

简介

条件结构能够根据某个特定的条件,结合内置的测试表达式功能,结合测试的结果状态值对于条件进行判断,然后选择执行合适的任务。在bash中,if命令是条件结构最简单的形式。
    shell中的if语句支持多种条件的决策形式:

单路决策 - 单分支if语句
    样式:
        if [ 条件 ]
        then
            指令
        fi
    特点:
        单一条件,只有一个输出
双路决策 - 双分支if语句
    样式:
        if [ 条件 ]
        then
            指令1
        else
            指令2
        fi
    特点:
        单一条件,两个输出
多路决策 - 多分支if语句
    样式:
        if [ 条件 ]
        then
            指令1
        elif [ 条件2 ]
        then
            指令2
        else
            指令3
        fi
    特点:
        n个条件,n+1个输出
单行命令写法
    if [ 条件1 ]; then 指令1; elif [ 条件2 ]; then 指令2; ... ; else 指令n; fi
关键点解读:
    1 if 和 then 配套使用
    2 if 和末尾的 fi 顺序反写

内嵌测试语句

    shell的if语句中关于条件判断这块内嵌了如下几种测试表达式语句:
        [ 表达式 ]     - 针对通用的判断场景 
        [[ 表达式 ]]   - 针对扩展的判断场景
        (( 命令 ))     - (())代替let命令来测试数值表达式

简单实践

实践1-单if实践

[root@localhost ~]# cat single_branch_if.sh
#!/bin/bash
# 单分支if语句的使用场景
​
# 定制普通变量
gender="$1"
​
# 条件判断逻辑
if [ "${gender}" == "nan" ]
then
   echo "您的性别是 男"
fi
脚本执行效果
[root@localhost ~]# /bin/bash single_branch_if.sh nv
[root@localhost ~]# /bin/bash single_branch_if.sh nan
您的性别是 男

实践2-双if实践

[root@localhost ~]# cat double_branch_if.sh
#!/bin/bash
# 双分支if语句的使用场景
​
# 定制普通变量
gender="$1"
​
# 条件判断逻辑
if [ "${gender}" == "nan" ]
then
   echo "您的性别是 男"
else
   echo "您的性别是 女"
fi
脚本执行效果
[root@localhost ~]# /bin/bash double_branch_if.sh
您的性别是 女
[root@localhost ~]# /bin/bash double_branch_if.sh nan
您的性别是 男
[root@localhost ~]# /bin/bash double_branch_if.sh xxx
您的性别是 女

实践3-多if实践

[root@localhost ~]# cat multi_branch_if.sh
#!/bin/bash
# 多分支if语句的使用场景
​
# 定制普通变量
gender="$1"
​
# 条件判断逻辑
if [ "${gender}" == "nan" ]
then
   echo "您的性别是 男"
elif [ "${gender}" == "nv" ]
then
   echo "您的性别是 女"
else
   echo "您的性别,我不知道"
fi
脚本执行效果
[root@localhost ~]# /bin/bash multi_branch_if.sh
您的性别,我不知道
[root@localhost ~]# /bin/bash multi_branch_if.sh nan
您的性别是 男
[root@localhost ~]# /bin/bash multi_branch_if.sh nv
您的性别是 女
[root@localhost ~]# /bin/bash multi_branch_if.sh xxx
您的性别,我不知道

if 案例实践

1.基础知识

2.简单实践

3.小结

服务管理

案例需求

要求脚本执行需要有参数,通过传入参数来实现不同的功能。
​
参数和功能详情如下:
    参数             执行效果
    start           服务启动中...
    stop            服务关闭中...
    restart         服务重启中...
    *               脚本 X.sh 使用方式 /bin/bash X.sh [ start|stop|restart ]

脚本内容

[root@localhost ~]# cat service_manager_if.sh
#!/bin/bash
# 功能:定制服务管理的功能
# 版本:v0.1
# 作者:书记
# 联系:www.superopsmsb.com
​
# 定制普通变量
service_ops="$1"
​
# 脚本基本判断
if [ $# -ne 1 ] 
then 
    echo -e "\e[31m$0 脚本的使用方式: $0 [ start | stop | restart ]\e[0m"
    exit
fi
​
# 脚本内容的判断
if [ "${service_ops}" == "start" ]
then
   echo -e "\e[31m服务启动中...\e[0m"
elif [ "${service_ops}" == "stop" ]
then
   echo -e "\e[31m服务关闭中...\e[0m"
elif [ "${service_ops}" == "restart" ]
then
   echo -e "\e[31m服务重启中...\e[0m"
else
   echo -e "\e[31m$0 脚本的使用方式: $0 [ start | stop | restart ]\e[0m"
fi
脚本执行效果
[root@localhost ~]# /bin/bash service_manager_if.sh
service_manager_if.sh 脚本的使用方式: service_manager_if.sh [ start | stop | restart ]
[root@localhost ~]# /bin/bash service_manager_if.sh start
服务启动中...
[root@localhost ~]# /bin/bash service_manager_if.sh stop
服务关闭中...
[root@localhost ~]# /bin/bash service_manager_if.sh restart
服务重启中...
[root@localhost ~]# /bin/bash service_manager_if.sh xxx
service_manager_if.sh 脚本的使用方式: service_manager_if.sh [ start | stop | restart ]

堡垒机登录

需求

在之前的堡垒机功能基础上,扩充条件判断效果

脚本内容

[root@localhost ~]# cat simple_jumpserver_if.sh
#!/bin/bash
# 功能:定制堡垒机的展示页面
# 版本:v0.4
# 作者:书记
# 联系:www.superopsmsb.com
​
# 定制普通变量
login_user='root'
login_pass='123456'
​
# 堡垒机的信息提示
echo -e "\e[31m \t\t 欢迎使用堡垒机"
echo -e "\e[32m-----------请选择你要登录的远程主机-----------
 1: 1.14 (nginx)
 2: 1.15 (tomcat)
 3: 1.19 (apache)
 q: 使用本地主机
----------------------------------------------\033[0m"
​
# 由于暂时没有学习条件判断,所以暂时选择 q
read -p "请输入您要选择的远程主机编号: " host_index
read -p "请输入登录本地主机的用户名: " user
read -s -p "请输入登录本地主机的密码: " password
echo
# 远程连接主机
if [[ ${user} == ${login_user} && ${password} == ${login_pass} ]] 
then
    echo -e "\e[31m主机登录验证成功\e[0m"
else
    echo -e "\e[31m您输入的用户名或密码有误\e[0m"
fi
脚本执行效果
[root@localhost ~]# /bin/bash simple_jumpserver_if.sh
                 欢迎使用堡垒机
-----------请选择你要登录的远程主机-----------
 1: 1.14 (nginx)
 2: 1.15 (tomcat)
 3: 1.19 (apache)
 q: 使用本地主机
----------------------------------------------
请输入您要选择的远程主机编号: q
请输入登录本地主机的用户名: root
请输入登录本地主机的密码:
主机登录验证成功
[root@localhost ~]# /bin/bash simple_jumpserver_if.sh
                 欢迎使用堡垒机
-----------请选择你要登录的远程主机-----------
 1: 1.14 (nginx)
 2: 1.15 (tomcat)
 3: 1.19 (apache)
 q: 使用本地主机
----------------------------------------------
请输入您要选择的远程主机编号: q
请输入登录本地主机的用户名: python
请输入登录本地主机的密码:
您输入的用户名或密码有误

嵌套if实践

1.基础知识

2.简单实践

3.小结

基础知识

简介

    一个if语句仅仅能够针对一个场景的多种情况。当我们面对多场景的条件判断的时候,一个if结构语句无法满足需求,这个时候,我们可以借助于嵌套if的结构语句来实现相应的效果。

注意:
    如果是多个独立的、彼此没有关联的业务场景,可以使用不同的if语句即可
    嵌套的if语句只能适用于彼此关联的业务场景

简单实践

案例需求

运维管理人员,通过监控平台获取站点的运行状态数据信息,当发现问题的时候,根据情况进行后续判断:
    状况1: 问题类型
        研发标识 - 交给开发团队
        测试标识 - 交给测试团队
        运维标识 - 交给运维团队
    状况2: 问题级别
        红灯 - 紧急故障
        黄灯 - 严重故障
        绿灯 - 一般故障
        灰灯 - 未知故障,后续操作

脚本内容

[root@localhost ~]# cat monitor_operator_if.sh
#!/bin/bash
# 功能:定制监控异常的处理措施
# 版本:v0.1
# 作者:书记
# 联系:www.superopsmsb.com
​
# 定制普通变量
monitor_type=(研发 测试 运维)
error_level=(红灯 黄灯 绿灯 灰灯)
​
# 监控平台的信息提示
echo -e "\e[31m \t\t 欢迎使用监控处理平台"
echo -e "\e[32m-----------请选择问题类型-----------
 1: 研发 2: 测试 3: 运维
----------------------------------\033[0m"
# 定制业务逻辑
read -p "请输入问题标识: " monitor_id
# 判断问题类型是否有效
if [ ${#monitor_type[@]} -lt ${monitor_id} ]
then
    echo -e "\e[31m无效标识,请输入正确的问题标识\e[0m"
else
    # 定制问题类型识别逻辑
    if [ ${monitor_type[$monitor_id-1]} == "研发" ]
    then
        echo -e "\e[31m转交研发团队处理\e[0m"
    elif [ ${monitor_type[$monitor_id-1]} == "测试" ]
    then
        echo -e "\e[31m转交测试团队处理\e[0m"
    elif [ ${monitor_type[$monitor_id-1]} == "运维" ]
    then
        echo -e "\e[32m-----------请选择故障级别-----------"
        echo " 1: 红灯 2: 黄灯 3: 绿灯 4: 灰灯"
        echo -e "----------------------------------\033[0m"
        read -p "请输入故障级别: " level_id
        # 判断故障级别是否有效
        if [ ${#error_level[@]} -lt ${level_id} ]
        then
            echo -e "\e[31m无效标识,请输入正确的故障级别\e[0m"
        else
            # 定制故障级别逻辑
            if [ ${error_level[$level_id-1]} == "红灯" ]
            then
                echo -e "\e[31m请按照 紧急故障 性质进行处理\e[0m"
            elif [ ${error_level[$level_id-1]} == "黄灯" ]
            then
                echo -e "\e[31m请按照 严重故障 性质进行处理\e[0m"
            elif [ ${error_level[$level_id-1]} == "绿灯" ]
            then
                echo -e "\e[31m请按照 一般故障 性质进行处理\e[0m"
            elif [ ${error_level[$level_id-1]} == "灰灯" ]
            then
                echo -e "\e[31m请按照 未知故障 性质进行处理\e[0m"
            fi
        fi
    fi
fi
脚本执行效果
[root@localhost ~]# /bin/bash monitor_operator_if.sh
                 欢迎使用监控处理平台
-----------请选择问题类型-----------
 1: 研发 2: 测试 3: 运维
----------------------------------
请输入问题标识: 4
无效标识,请输入正确的问题标识
[root@localhost ~]# /bin/bash monitor_operator_if.sh
                 欢迎使用监控处理平台
-----------请选择问题类型-----------
 1: 研发 2: 测试 3: 运维
----------------------------------
请输入问题标识: 1
转交研发团队处理
[root@localhost ~]# /bin/bash monitor_operator_if.sh
                 欢迎使用监控处理平台
-----------请选择问题类型-----------
 1: 研发 2: 测试 3: 运维
----------------------------------
请输入问题标识: 3
-----------请选择故障级别-----------
 1: 红灯 2: 黄灯 3: 绿灯 4: 灰灯
----------------------------------
请输入故障级别: 1
请按照 紧急故障 性质进行处理
[root@localhost ~]# /bin/bash monitor_operator_if.sh
                 欢迎使用监控处理平台
-----------请选择问题类型-----------
 1: 研发 2: 测试 3: 运维
----------------------------------
请输入问题标识: 3
-----------请选择故障级别-----------
 1: 红灯 2: 黄灯 3: 绿灯 4: 灰灯
----------------------------------
请输入故障级别: 6
无效标识,请输入正确的故障级别

其他实践

1.基础知识

2.简单实践

3.小结

条件进阶

简介

    if条件控制语句支持(())来代替let命令测试表达式的执行效果,支持[[]]实现正则级别的内容匹配。
表达式的样式如下:
if (( 表达式 ))  或 [[ 内容匹配 ]]
then
    指令
fi

实践1-(()) 计算条件匹配

查看脚本内容
[root@localhost ~]# cat odd_even_if.sh
#!/bin/bash
# (()) 在if分支中的应用
​
# 接收一个数字
read -p "请输入一个数字: " num
​
# 定制数字奇数和偶数判断
if (( ${num} % 2 == 0 ))
then
    echo -e "\e[31m ${num} 是一个偶数\e[0m"
else
    echo -e "\e[31m ${num} 是一个奇数\e[0m"
fi
脚本执行效果
[root@localhost ~]# /bin/bash odd_even_if.sh
请输入一个数字: 2
 2 是一个偶数
[root@localhost ~]# /bin/bash odd_even_if.sh
请输入一个数字: 1
 1 是一个奇数

实践2-[[]]扩展匹配条件

查看脚本内容
[root@localhost ~]# cat condition_extend_if.sh
#!/bin/bash
# [[]] 在if分支中的应用
​
# 接收一个数字
read -p "请输入一个单词: " string
​
# 判断内容是否是我们想要的
if [[ ${string} == v* ]]
then
    echo -e "\e[31m ${num} 是满足条件的单词\e[0m"
else
    echo -e "\e[31m ${num} 不满足条件\e[0m"
fi
执行脚本效果
[root@localhost ~]# /bin/bash condition_extend_if.sh
请输入一个单词: very
  是满足条件的单词
[root@localhost ~]# /bin/bash condition_extend_if.sh
请输入一个单词: hello
  不满足条件

实践3-[[]]扩展实践

#!/bin/bash
# [[]] 在if分支中的应用
​
# 接收一个数字
read -p "请输入你的身高(m为单位): " height
​
# 身高判断逻辑
if [[ ! ${height} =~ ^[0-2](\.[0-9]{,2})?$ ]]
then 
    echo -e "\e[31m你确定自己的身高是 ${height} ?\e[0m"
else
    echo -e "\e[31m我说嘛,${height} 才是你的身高!\e[0m"
fi
脚本执行效果
[root@localhost ~]# /bin/bash person_height_if.sh
请输入你的身高(m为单位): 3
你确定自己的身高是 3 ?
[root@localhost ~]# /bin/bash person_height_if.sh
请输入你的身高(m为单位): 1.2
我说嘛,1.2 才是你的身高!

单行命令

简介

所谓的单行命令,其实指的是对于简单的if条件判断,我们可以直接一行显示,减少代码的行数

简单实践

示例1-命令行的if语句
[root@localhost ~]# num1=3 num2=1
[root@localhost ~]# if [ $num1 -gt $num2 ]; then echo "$num1 数字大"; else echo "$num2 数字大"; fi
3 数字大
[root@localhost ~]# num1=3 num2=9
[root@localhost ~]# if [ $num1 -gt $num2 ]; then echo "$num1 数字大"; else echo "$num2 数字大"; fi
9 数字大
示例2-使用逻辑表达式来满足if效果
[root@localhost ~]# num1=3 num2=1
[root@localhost ~]# [ $num1 -gt $num2 ] && echo "$num1 数字大" || echo "$num2 数字大"
3 数字大
[root@localhost ~]# num1=3 num2=9
[root@localhost ~]# [ $num1 -gt $num2 ] && echo "$num1 数字大" || echo "$num2 数字大"
9 数字大

case条件控制

语法解读

1.基础知识

2.简单实践

3.小结

基础知识

简介

case命令是一个多路分支的命令,它可以来代替 if/elif相关的命令,在case语句中,它通过引入一个变量接收用户输入的数据,然后依次与相关的值进行匹配判断,一旦找到对应的匹配值后,就执行相关的语句。

语法格式

case 变量名 in
   值1)
      指令1
         ;;
   ...
   值n)
       指令n
         ;;
esac
注意:
    首行关键字是case,末行关键字esac
    选择项后面都有 )
    每个选择的执行语句结尾都有两个分号;
    

简单实践

案例需求

改造多分支if语句对脚本进行升级
    要求脚本执行需要有参数,通过传入参数来实现不同的功能。
​
参数和功能详情如下:
    参数         执行效果
    start       服务启动中...
    stop        服务关闭中...
    restart     服务重启中...
    *           脚本 X.sh 使用方式 X.sh [ start|stop|restart ]

脚本效果

查看脚本内容
[root@localhost ~]# cat service_manager_case.sh
#!/bin/bash
# 功能:定制服务管理的功能
# 版本:v0.1
# 作者:书记
# 联系:www.superopsmsb.com
​
# 定制普通变量
service_ops="$1"
​
# 脚本内容的判断
case "${service_ops}" in
    "start")
        echo -e "\e[31m服务启动中...\e[0m";;
    "stop")
        echo -e "\e[31m服务关闭中...\e[0m";;
    "restart")
        echo -e "\e[31m服务重启中...\e[0m";;
    "start")
        echo -e "\e[31m服务启动中...\e[0m";;
    *)
        echo -e "\e[31m$0 脚本的使用方式: $0 [ start | stop | restart ]\e[0m";;
esac
脚本执行效果
[root@localhost ~]# /bin/bash service_manager_case.sh
service_manager_case.sh 脚本的使用方式: service_manager_case.sh [ start | stop | restart ]
[root@localhost ~]# /bin/bash service_manager_case.sh start
服务启动中...
[root@localhost ~]# /bin/bash service_manager_case.sh stop
服务关闭中...
[root@localhost ~]# /bin/bash service_manager_case.sh restart
服务重启中...
[root@localhost ~]# /bin/bash service_manager_case.sh xxx
service_manager_case.sh 脚本的使用方式: service_manager_case.sh [ start | stop | restart ]

case实践

1.环境标准化、

2.小结

环境标准化

案例需求

    由于项目环境复杂,虽然我们创建了大量的脚本,但是管理起来不方便,需要我们做一个简单的脚本执行管理平台,输入不同的环境关键字,罗列该环境下的相关脚本。
信息提示
        欢迎使用脚本管理平台
-----------请选择功能场景-----------
 1: 系统环境下脚本
 2: web环境下脚本
 3: 数据库环境下脚本
 4: 存储环境下脚本
 5: 其他环境下脚本
----------------------------------

准备工作

mkdir os web sql storage other
touch {os/os-{1..3}.sh,web/web-{1..4}.sh,sql/sql-{1..5}.sh,storage/st-{1..2}.sh,other/other.sh}

脚本内容

查看脚本内容
[root@localhost ~]# cat scripts_manager_case.sh
#!/bin/bash
# 功能:定制服务管理的功能
# 版本:v0.1
# 作者:书记
# 联系:www.superopsmsb.com
​
# 定制数组变量
env_array=(os web sql storage other)
​
# 监控平台的信息提示
echo -e "\e[31m        欢迎使用脚本管理平台"
echo -e "\e[32m-----------请选择功能场景-----------
 1: 系统环境下脚本
 2: web环境下脚本
 3: 数据库环境下脚本
 4: 存储环境下脚本
 5: 其他环境下脚本
----------------------------------\033[0m"
# 定制业务逻辑
read -p "请输入功能标识: " env_id
​
# 脚本内容的判断
case "${env_array[$env_id-1]}" in
    "os")
        echo -e "\e[31m系统环境下脚本文件有:\e[0m"
        ls os;;
    "web")
        echo -e "\e[31mweb环境下脚本文件有:\e[0m"
        ls web;;
    "sql")
        echo -e "\e[31m数据库环境下脚本文件有:\e[0m"
        ls sql;;
    "storage")
        echo -e "\e[31m存储环境下脚本文件有:\e[0m"
        ls storage;;
    "other")
        echo -e "\e[31m其他环境下脚本文件有:\e[0m"
        ls other;;
    *)
        echo -e "\e[31m请输入有效的功能场景标识\e[0m";;
esac
脚本执行效果
[root@localhost ~]# /bin/bash scripts_manager_case.sh
        欢迎使用脚本管理平台
-----------请选择功能场景-----------
 1: 系统环境下脚本
 2: web环境下脚本
 3: 数据库环境下脚本
 4: 存储环境下脚本
 5: 其他环境下脚本
----------------------------------
请输入功能标识: 6
请输入有效的功能场景标识
[root@localhost ~]# /bin/bash scripts_manager_case.sh 3
        欢迎使用脚本管理平台
-----------请选择功能场景-----------
 1: 系统环境下脚本
 2: web环境下脚本
 3: 数据库环境下脚本
 4: 存储环境下脚本
 5: 其他环境下脚本
----------------------------------
请输入功能标识: 3
数据库环境下脚本文件有:
sql-1.sh  sql-2.sh  sql-3.sh  sql-4.sh  sql-5.sh

嵌套实践

1.基础知识

2.简单实践

3.小结

基础知识

简介

这里的嵌套实践,与if语句的嵌套实践,基本一致,只不过组合的方式发生了一些变化。常见的组合样式如下:
case嵌套if语句
    case "变量" in
        "值1")
            if [ 条件判断 ]
            ...
            ;;
        ...
    esac
case嵌套case语句
    case "变量" in
        "值1")
            case语句
        ...
    esac
if嵌套case语句
    if [ 条件判断 ]
    then
        case "变量名" in
           "值1")
              指令1;;
           ...
        esac        
    else
        ...
    fi

简单实践

案例需求

场景简介:
    火车站安检
        安检失败
            - 携带违禁物品禁止进站
        安检成功后进行火车票检查
            - 允许登上上火车
            - 禁止登上火车

实践1-case嵌套if语句

查看脚本内容
[root@localhost ~]# cat case_if.sh
#!/bin/bash
# 功能:case嵌套if语句实践
​
# 定制业务逻辑
read -p "是否携带违禁物品: " safe_check
# 业务逻辑定制
case "${safe_check}" in
    "true")
        echo -e "\e[31m不允许进入火车站\e[0m";;
    "false")
        read -p "火车票是否过期: " ticket_check
        if [ ${ticket_check} == "true" ]
        then
            echo -e "\e[31m不允许登上火车站\e[0m"
        else
            echo -e "\e[31m允许登上火车站\e[0m"
        fi;;
    *)
        echo -e "\e[31m再检查一遍\e[0m";;
esac
脚本执行效果
[root@localhost ~]# /bin/bash case_if.sh
是否携带违禁物品: true
不允许进入火车站
[root@localhost ~]# /bin/bash case_if.sh
是否携带违禁物品: false
火车票是否过期: true
不允许登上火车站
[root@localhost ~]# /bin/bash case_if.sh
是否携带违禁物品: false
火车票是否过期: false
允许登上火车站
[root@localhost ~]# /bin/bash case_if.sh
是否携带违禁物品: hah
再检查一遍

实践2-case嵌套case语句

查看脚本内容
[root@localhost ~]# cat case_case.sh
#!/bin/bash
# 功能:case嵌套case语句实践
​
# 定制业务逻辑
read -p "是否携带违禁物品: " safe_check
# 业务逻辑定制
case "${safe_check}" in
    "true")
        echo -e "\e[31m不允许进入火车站\e[0m";;
    "false")
        read -p "火车票是否过期: " ticket_check
        case "${ticket_check}" in
            "true")
                echo -e "\e[31m不允许登上火车站\e[0m";;
            "false")
                echo -e "\e[31m允许登上火车站\e[0m";;
            *)
                echo -e "\e[31m再检查一遍\e[0m";;
        esac;;
    *)
        echo -e "\e[31m再检查一遍\e[0m";;
esac

实践3-if嵌套case语句

查看脚本内容
[root@localhost ~]# cat if_case.sh
#!/bin/bash
# 功能:if嵌套case语句实践
​
# 定制业务逻辑
read -p "是否携带违禁物品: " safe_check
# 业务逻辑定制
if [ "${safe_check}" == "true" ]
then
    echo -e "\e[31m不允许进入火车站\e[0m"
elif [ "${safe_check}" == "false" ]
then 
    read -p "火车票是否过期: " ticket_check
    case ${ticket_check} in
        "true")
            echo -e "\e[31m不允许登上火车站\e[0m";;
        "false")
            echo -e "\e[31m允许登上火车站\e[0m";;
        *)
            echo -e "\e[31m再检查一遍\e[0m";;
    esac
else
    echo -e "\e[31m再检查一遍\e[0m"
fi

嵌套案例

1.基础知识

2.简单实践

3.小结

案例需求

运维管理人员,通过监控平台获取站点的运行状态数据信息,当发现问题的时候,根据情况进行后续判断:
    状况1: 问题类型
        研发标识 - 交给开发团队
        测试标识 - 交给测试团队
        运维标识 - 交给运维团队
    状况2: 问题级别
        红灯 - 紧急故障
        黄灯 - 严重故障
        绿灯 - 一般故障
        灰灯 - 未知故障,后续操作

简单实践

实践-改造嵌套if的监控管理脚本

查看脚本内容
[root@localhost ~]# cat monitor_operator_if_case.sh
# 功能:定制监控异常的处理措施
# 版本:v0.2
# 作者:书记
# 联系:www.superopsmsb.com
​
# 定制普通变量
monitor_type=(研发 测试 运维)
error_level=(红灯 黄灯 绿灯 灰灯)
​
# 监控平台的信息提示
echo -e "\e[31m \t\t 欢迎使用监控处理平台"
echo -e "\e[32m-----------请选择问题类型-----------
 1: 研发 2: 测试 3: 运维
----------------------------------\033[0m"
# 定制业务逻辑
read -p "请输入问题标识: " monitor_id
# 判断问题类型是否有效
if [ ${#monitor_type[@]} -lt ${monitor_id} ]
then
    echo -e "\e[31m无效标识,请输入正确的问题标识\e[0m"
else
    # 定制问题类型识别逻辑
    case ${monitor_type[$monitor_id-1]} in
        "研发")
            echo -e "\e[31m转交研发团队处理\e[0m";;
        "测试")
            echo -e "\e[31m转交测试团队处理\e[0m";;
        "运维")
            echo -e "\e[32m-----------请选择故障级别-----------"
            echo " 1: 红灯 2: 黄灯 3: 绿灯 4: 灰灯"
            echo -e "----------------------------------\033[0m"
            read -p "请输入故障级别: " level_id
            # 定制故障级别逻辑
            case ${error_level[$level_id-1]} in
                "红灯")
                    echo -e "\e[31m请按照 紧急故障 性质进行处理\e[0m";;
                "黄灯")
                    echo -e "\e[31m请按照 严重故障 性质进行处理\e[0m";;
                "绿灯")
                    echo -e "\e[31m请按照 一般故障 性质进行处理\e[0m";;
                "灰灯")
                    echo -e "\e[31m请按照 未知故障 性质进行处理\e[0m";;
                *)
                    echo -e "\e[31m无效标识,请输入正确的故障级别\e[0m";;
            esac
   esac
fi
脚本执行效果
[root@localhost ~]# /bin/bash monitor_operator_if_case.sh
                 欢迎使用监控处理平台
-----------请选择问题类型-----------
 1: 研发 2: 测试 3: 运维
----------------------------------
请输入问题标识: 1
转交研发团队处理
[root@localhost ~]# /bin/bash monitor_operator_if_case.sh
                 欢迎使用监控处理平台
-----------请选择问题类型-----------
 1: 研发 2: 测试 3: 运维
----------------------------------
请输入问题标识: 4
无效标识,请输入正确的问题标识
​
[root@localhost ~]# /bin/bash monitor_operator_if_case.sh
                 欢迎使用监控处理平台
-----------请选择问题类型-----------
 1: 研发 2: 测试 3: 运维
----------------------------------
请输入问题标识: 3
-----------请选择故障级别-----------
 1: 红灯 2: 黄灯 3: 绿灯 4: 灰灯
----------------------------------
请输入故障级别: 3
请按照 一般故障 性质进行处理
[root@localhost ~]# /bin/bash monitor_operator_if_case.sh
                 欢迎使用监控处理平台
-----------请选择问题类型-----------
 1: 研发 2: 测试 3: 运维
----------------------------------
请输入问题标识: 3
-----------请选择故障级别-----------
 1: 红灯 2: 黄灯 3: 绿灯 4: 灰灯
----------------------------------
请输入故障级别: 6
无效标识,请输入正确的故障级别

for循环

for基础

1.基础知识

2.简单实践

3.小结

基础知识

简介

    生产工作中,我们有可能会遇到一种场景,需要重复性的执行相同的动作,我们在shell编程的过程中,我们可以借助于循环逻辑的方法来进行处理。
循环逻辑语法解析:
    关键字 [ 条件 ]
    do
        执行语句
    done
    
注意:
    这里的关键字主要有四种:
        for     - 循环遍历一个元素列表
        while   - 满足条件情况下一直循环下去
        until   - 不满足条件情况下一直循环下去
        select  - 一种特殊的循环遍历,侧重于遍历用户输入,一般结合case等语句使用

简单实践

for语法解析

场景:遍历列表
    for 值 in 列表
    do
       执行语句
    done
注意:
    ”for” 循环总是接收 “in” 语句之后的某种类型的字列表
    执行次数和list列表中常数或字符串的个数相同,当循环的数量足够了,就自动退出

列表生成

样式1:手工列表
    - 1 2 3 4 5 6 7
样式2:定制列表
    - {1..7}
样式3:命令生成
    - $(seq 1 7)
样式4:脚本参数
    - $@ $*

实践1-手工列表

查看脚本内容
[root@localhost ~]# cat for_hand_list.sh
#!/bin/bash
# 功能:手工列表 for循环
for i in yuwen shuxue lishi
do
  echo "列表元素: ${i}"
done
​
脚本执行后效果
[root@localhost ~]# /bin/bash for_hand_list.sh
列表元素: yuwen
列表元素: shuxue
列表元素: lishi

实践2-定制列表

查看脚本内容
[root@localhost ~]# cat for_define_list.sh
#!/bin/bash
# 功能:定制列表 for循环
for i in {1..3}
do
  echo "列表元素: ${i}"
done
​
脚本执行后效果
[root@localhost ~]# /bin/bash for_define_list.sh
列表元素: 1
列表元素: 2
列表元素: 3

实践3-命令生成

查看脚本内容
[root@localhost ~]# cat for_cmd_list.sh
#!/bin/bash
# 功能:命令生成列表 for循环
for i in $(seq 1 3)
do
  echo "列表元素: ${i}"
done
​
脚本执行后效果
[root@localhost ~]# /bin/bash for_cmd_list.sh
列表元素: 1
列表元素: 2
列表元素: 3

实践4-脚本参数

查看脚本内容
[root@localhost ~]# cat for_arg_list.sh
#!/bin/bash
# 功能:脚本参数列表 for循环
for i in $@
do
  echo "列表元素: ${i}"
done
​
脚本执行后效果
[root@localhost ~]# /bin/bash for_arg_list.sh 1 2 3
列表元素: 1
列表元素: 2
列表元素: 3

for循环案例

1.普通循环

2.赋值循环

3.小结 

普通循环

简介

所谓的普通循环,仅仅是在特定的范围循环中,对相关命令进行重复性的操作

批量实践1- 批量创建多个用户

查看脚本内容
[root@localhost ~]# cat for_add_user.sh
#!/bin/bash
# 功能:for批量创建用户
​
# 定制批量创建用户的业务逻辑
for i in {1..5}
do
    # 创建用户
    useradd user-$i
    echo -e "\e[31m用户 user-$i 创建成功\e[0m"
done
脚本执行后效果
[root@localhost ~]# /bin/bash for_add_user.sh
用户 user-1 创建成功
用户 user-2 创建成功
用户 user-3 创建成功
用户 user-4 创建成功
用户 user-5 创建成功

批量实践2- 批量对特定网段的主机进行扫描

查看脚本内容
[root@localhost ~]# cat for_host_check.sh
#!/bin/bash
# 功能:for批量检测网段主机存活情况
​
# 定制普通变量
netsub='192.168.66'
net_file='/tmp/host.txt'
​
# 保证文件可用
[ -f ${net_file} ] && > ${net_file}
​
# 定制批量检测网段主机状态逻辑
for ip in {1..254}
do
    # 测试主机连通性
    host_status=$(ping -c1 -W1 $netsub.$ip >/dev/null 2>&1 && echo "UP" || echo "DOWN")
    echo "$netsub.$ip 主机状态: $host_status" >> ${net_file}
done
​
# 信息输出
live_num=$(grep UP ${net_file} | wc -l)
unlive_num=$(grep DOWN ${net_file} | wc -l)
echo -e "\e[31m${netsub}.0 网段主机存活情况\e[0m"
echo "------------------------------------"
echo -e "\e[32m${netsub}.0 网段存活主机数量: ${live_num}\e[0m"
echo -e "\e[32m${netsub}.0 网段异常主机数量: ${unlive_num}\e[0m"
脚本执行效果
[root@localhost ~]# /bin/bash for_host_check.sh
1.0 网段主机存活情况
------------------------------------
1.0 网段存活主机数量: 2
1.0 网段异常主机数量: 252
​
[root@localhost ~]# grep UP /tmp/host.txt
1.2 主机状态: UP
1.12 主机状态: UP

赋值循环

简介

所谓的赋值循环,指的是在for循环过程中进行数据的统计等相关计算操作

统计实践1- 计算 1+2+...+100 的结果

查看脚本内容
[root@localhost ~]# cat for_odd_num.sh
#!/bin/bash
# 功能:for统计数据之和
​
# 定制普通变量
all_sum=0
odd_sum=0
​
# 定制所有数据求和逻辑
for i in {1..100}
do
  let all_sum+=i
done
​
# 定制所有奇数求和逻辑
for i in {1..100..2}
do
  let odd_sum+=i
done
​
# 信息输出
echo -e "\e[31m所有数据之和: ${all_sum}\e[0m"
echo -e "\e[31m所有奇数之和: ${odd_sum}\e[0m"
​
脚本执行后效果
[root@localhost ~]# /bin/bash for_odd_sum.sh
所有数据之和: 5050
所有奇数之和: 2500

for (())案例

1.基础知识

2.循环案例

3.小结 

基础实践

简介

    在for循环的语法中,它还支持一种包含赋值+循环双功能的语法,也就是双小括号(()),这种语法的语法格式如下:
    样式1: 单元素样式
        for (( i=0; i<10; i++ ))
    样式2: 多元素样式
        for (( i=0,j=0; i<10; i++,j++ ))
功能解读
    1 第一部分定制一个包含初始值的变量名
    2 第二部分定制循环的结束条件
    3 第三部分定制循环过程中的变量变化效果
        - 为了让循环出现结束
注意事项:
    1 变量的赋值可以包含空格
    2 条件中的变量不能用$符号
    3 第三部分的数据操作过程不用 expr 格式

实践1-(())简单使用

输出1-5的数字
[root@localhost ~]# for ((i=1;i<=5;i++));do echo $i;done
1
2
3
4
5
​
输出1-10中的所有奇数
[root@localhost ~]# for ((i=1;i<=10;i+=2));do echo $i;done
1
3
5
7
9
​
输出1-10中的所有偶数
[root@localhost ~]# for ((i=2;i<=10;i+=2));do echo $i;done
2
4
6
8
10

实践2-100个数字的求和

查看脚本内容
[root@localhost ~]# cat for_odd_num.sh
#!/bin/bash
# 功能:for统计数据之和
​
# 定制普通变量
all_sum=0
odd_sum=0
​
# 定制所有数据求和逻辑
for ((i=1;i<=100;i++))
do
  let all_sum+=i
done
​
# 定制所有奇数求和逻辑
for ((i=1;i<=100;i+=2))
do
  let odd_sum+=i
done
​
# 信息输出
echo -e "\e[31m所有数据之和: ${all_sum}\e[0m"
echo -e "\e[31m所有奇数之和: ${odd_sum}\e[0m"
​
脚本执行后效果
[root@localhost ~]# /bin/bash for_odd_sum.sh
所有数据之和: 5050
所有奇数之和: 2500

循环案例

实践1-命令行进度条数字

[root@localhost ~]# for ((i = 0; i<=100; ++i)); do printf "\e[4D%3d%%" $i;sleep 0.1s; done
 27%
... ...
[root@localhost ~]# for ((i = 0; i<=100; ++i)); do printf "\e[4D%3d%%" $i;sleep 0.1s; done
 99%
​
命令解读:
    %3d%% 指的是 3个数字位置 + 1个%位置,共计4个位置
    防止信息输出的叠加,采用\e[4D,每次输出信息的时候,光标左移4个位置,信息不会出现叠加
    
\e[3D 的演示
[root@localhost ~]# for ((i = 0; i <= 100; ++i)); do printf "\e[2D%3d%%" $i;sleep 0.1s; done
                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 56 5 5 5 6 6 6 6 6 6 6 6 6 6 7 7 7 7 7 7 7 7 7 7 8 8 8 8 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9100%[root@localhost ~]#

嵌套循环

1.基础知识

2.简单实践

3.小结

基础知识

简介

这里的嵌套实践,与选择语句的嵌套实践基本一致,只不过组合的方式发生了一些变化。常见的组合样式如下:
for嵌套for语句
    for 循环列表1
    do
        for 循环列表2
        do
            ...
        done
    done
for嵌套if|case语句
    for 循环列表
    do
        if 条件判断语句
        或
        case 条件判断语句
    done
if语句嵌套for语句
    if 条件判断
    then
        for 循环列表语句
    fi
    
case语句嵌套for语句   
    case 条件判断
        for 循环列表语句
        ;;
    esac

简单实践

for嵌套if语句实践1-判断目录中的文件类型

准备工作
mkdir dir/{server,soft,scripts,logs} -p
touch dir/{{a..c}.sh,{1..3}.txt}
查看脚本内容
[root@localhost ~]# cat file_type_for_if.sh
#!/bin/bash
# 功能:for嵌套if查看目录下的文件类型
​
# 定制普通变量
dir_name='dir'
​
# 获取所有文件列表
for file in $(ls dir)
do
    # 判断文件类型
    if [ -d ${dir_name}/${file} ]
    then
        echo -e "\e[31m${dir_name}/${file} 是一个目录文件\e[0m"
    elif [ -f ${dir_name}/${file} ]
    then
        echo -e "\e[31m${dir_name}/${file} 是一个普通文件\e[0m"
    fi
done
脚本执行效果
[root@localhost ~]# /bin/bash file_type_for_if.sh
dir/1.txt 是一个普通文件
dir/2.txt 是一个普通文件
dir/3.txt 是一个普通文件
dir/a.sh 是一个普通文件
dir/b.sh 是一个普通文件
dir/c.sh 是一个普通文件
dir/logs 是一个目录文件
dir/scripts 是一个目录文件
dir/server 是一个目录文件
dir/soft 是一个目录文件
收尾动作
[root@localhost ~]# rm -rf dir

if嵌套for语句实践3-获取系统支持的shell类型

查看脚本内容
[root@localhost ~]# cat os_shell_if_for.sh
#!/bin/bash
# 功能:if嵌套for查看系统支持的shell类型
​
# 定制普通变量
shell_file='/etc/shells'
​
# 获取所有文件列表
if [ -f ${shell_file} ]
then
    for shell in $(grep sh /etc/shells)
    do
        echo -e "\e[31m当前系统支持的shell类型有: ${shell}\e[0m"
    done
else
    echo -e "\e[31m没有 ${shell_file} 文件\e[0m"
fi
脚本执行效果
[root@localhost ~]# /bin/bash os_shell_if_for.sh
当前系统支持的shell类型有: /bin/sh
当前系统支持的shell类型有: /bin/bash
当前系统支持的shell类型有: /usr/bin/sh
当前系统支持的shell类型有: /usr/bin/bash

综合案例

1.信息收集

2.其他实践

3.小结 

信息收集

案例需求

    根据提示信息,选择输出 cpu 或者 内存信息。

脚本实践-采集系统负载信息

查看脚本内容
[root@localhost ~]# cat systemctl_load.sh
#!/bin/bash
# 功能:采集系统负载信息
# 版本:v0.2
# 作者:书记
# 联系:www.superopsmsb.com
​
# 定制资源类型
resource_type=(CPU MEM)
cpu_attribute=(1 5 15)
free_attribute=(总量 使用 空闲)
​
# 获取相关的属性信息
cpu_load=($(uptime | tr -s " " | cut -d " " -f 11-13 | tr "," " "))
free_info=($(free -m | grep Mem | tr -s " " | cut -d " " -f 2-4))
# 服务的操作提示
echo -e "\e[31m---------------查看资源操作动作---------------
 1: CPU  2: MEM
-------------------------------------------"'\033[0m'
# 选择服务操作类型
read -p "> 请输入要查看的资源信息类型: " resource_id
echo
if [ ${resource_type[$resource_id-1]} == "CPU" ]
then
    echo -e "\e[31m\t系统CPU负载信息\e[0m"
    echo -e "\e[32m================================"
    for index in ${!cpu_attribute[@]}
    do
        echo "CPU ${cpu_attribute[$index]} min平均负载为: ${cpu_load[$index]}" 
    done
    echo -e "================================\e[0m"
elif [ ${resource_type[$resource_id-1]} == "MEM" ]
then
    echo -e "\e[31m\t系统内存负载信息\e[0m"
    echo -e "\e[32m================================"
    for index in ${!free_attribute[@]}
    do
        echo "内存 ${free_attribute[$index]} 信息为: ${free_info[$index]} M" 
    done
    echo -e "================================\e[0m"
fi
脚本使用效果
[root@localhost ~]# /bin/bash systemctl_load.sh
---------------查看资源操作动作---------------
 1: CPU  2: MEM
-------------------------------------------
> 请输入要查看的资源信息类型: 1
​
        系统CPU负载信息
================================
CPU 1 min平均负载为: 0.00
CPU 5 min平均负载为: 0.01
CPU 15 min平均负载为: 0.05
================================
[root@localhost ~]# /bin/bash systemctl_load.sh
---------------查看资源操作动作---------------
 1: CPU  2: MEM
-------------------------------------------
> 请输入要查看的资源信息类型: 2
​
        系统内存负载信息
================================
内存 总量 信息为: 3770 M
内存 使用 信息为: 247 M
内存 空闲 信息为: 3302 M
================================

while循环

while基础

1.基础知识

2.简单实践

3.小结

基础知识

简介

    while命令有点像 if/then 和 for循环之间的结合,while走循环之前会对输入的值进行条件判断,如果满足条件的话,才会进入到循环体中执行对应的语句,否则的话就退出循环。

while语法解析

场景:只要条件满足,就一直循环下去
    while [ 条件判断 ]
    do
       执行语句
    done
注意:
    条件支持的样式 命令、[[ 字符串表达式 ]]、(( 数字表达式 ))
    true是一个特殊的条件,代表条件永远成立

简单实践

实践1-输出制定的范围数字

[root@localhost ~]# cat while_num_list.sh
#!/bin/bash
# 功能:while的输出5范围以内的数字
​
# 定制初始变量值
a=1
​
# 定制内容输出逻辑
while [ "${a}" -le 5 ]
do
   echo -n "${a} "
   # 每输出一次数据,数据值+1
   a=$((a+1))
done
echo
脚本执行后效果
[root@localhost ~]# /bin/bash while_num_list.sh
1 2 3 4 5

while案例

1.案例实践

2.read实践

3.小结 

案例实践

统计实践1- 计算1+2+...+100 的结果

查看脚本内容
[root@localhost ~]# cat while_odd_num.sh
#!/bin/bash
# 功能:while统计数据之和
​
# 定制普通变量
all_sum=0
odd_sum=0
​
# 定制所有数据求和逻辑
i=1
while ((i<=100))
do
  let all_sum+=i
  let i++
done
​
# 定制所有奇数求和逻辑
i=1
while ((i<=100))
do
  let odd_sum+=i
  let i+=2
done
​
# 信息输出
echo -e "\e[31m所有数据之和: ${all_sum}\e[0m"
echo -e "\e[31m所有奇数之和: ${odd_sum}\e[0m"
​
脚本执行后效果
[root@localhost ~]# /bin/bash while_odd_num.sh
所有数据之和: 5050
所有奇数之和: 2500

实践2-持续检测网站存活

查看文件内容
[root@localhost ~]# cat while_site_healthcheck.sh
#!/bin/bash
# 功能:定制站点的检测功能
# 版本:v0.1
# 作者:书记
# 联系:www.superopsmsb.com
​
# 定制普通变量
read -p "> 请输入待测试站点域名: " site_addr
​
# 持久检测站点状态
while true
do
  wget --spider -T5 -q -t2 ${site_addr} && echo "${site_addr} 站点正常" || echo "${site_addr} 站点异常"
  sleep 1
done
脚本执行效果
[root@localhost ~]# /bin/bash while_site_healthcheck.sh
> 请输入待测试站点域名: www.baidu.com
www.baidu.com 站点正常
www.baidu.com 站点正常
...

read实践

功能简介

    while中有一种特殊的语法,while read line 它可以从文本中逐行读取相关的内容,然后存储到一个临时变量line中,然后我们后续就可以逐行对文本内容进行操作

语法解读

样式1: cat提前读             
cat a.log | while read line
do                         
    echo "File: ${line}"     
done                       
样式2: exec提前读    
exec 0< a.log    
while read line  
do               
    echo "${line}"
done
样式3:结尾导入读
while read line
do
    echo "File: ${line}"
done < a.log
​
注意:
    方法1和3可以直接在命令行来实验,但是方法2必须在脚本中才能实验

实践1-命令行实践

方法1实践读取文件
[root@localhost ~]# cat /etc/hosts | while read line;do echo "File: ${line}";done
File: 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
File: ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
​
方法3实践读取文件
[root@localhost ~]# while read line;do echo "File: ${line}";done < /etc/hosts
File: 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
File: ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

实践2-脚本实践

方法2实践读取文件
[root@localhost ~]# cat while_read_file.sh
#!/bin/bash
# 功能:while的exec读取文件内容
​
# 定制普通变量
read -p "> 请输入待读取的文件路径: " file_path
​
# 持久检测站点状态
exec < ${file_path}    
while read line  
do               
    echo "File: ${line}"
done
脚本执行效果
[root@localhost ~]# /bin/bash while_read_file.sh
> 请输入待读取的文件路径: /etc/hosts
File: 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
File: ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

嵌套案例

1.基础知识

2.简单实践

3.小结

基础知识

简介

这里的嵌套实践,与选择语句的嵌套实践基本一致,只不过组合的方式发生了一些变化。常见的组合样式如下:
while嵌套while语句
    while 循环条件
    do
        while 循环条件语句
    done
while嵌套if语句
    while 循环条件
    do
        if 条件控制语句
    done    

while嵌套if语句实践2-手机发送短信1次/1毛,余额低于1毛提示无法发送请充值

[root@localhost ~]# cat while_mobile_bill.sh
#!/bin/bash
# 功能:while提示收集发短信
​
# 定制普通变量
read -p "> 请输入收集话费余额(元): " mobile_bill
​
# 定制普通变量
sms_num=0
bull_count=$[$mobile_bill * 10]
while [ $bull_count -ge 0 ]
do
    sms_num=$(($sms_num+1))
    if [ $bull_count -lt 1 ];then
        echo "剩余费用不足,请充话费!"
    else
        echo "截至目前,您已发送 ${sms_num} 条短信。"
    fi
    bull_count=$(($bull_count-1))
    sleep 0.1
done
脚本执行效果
[root@localhost ~]# /bin/bash while_mobile_bill.sh
> 请输入收集话费余额(元): 1
截至目前,您已发送 1 条短信。
截至目前,您已发送 2 条短信。
截至目前,您已发送 3 条短信。
截至目前,您已发送 4 条短信。
截至目前,您已发送 5 条短信。
截至目前,您已发送 6 条短信。
截至目前,您已发送 7 条短信。
截至目前,您已发送 8 条短信。
截至目前,您已发送 9 条短信。
截至目前,您已发送 10 条短信。
剩余费用不足,请充话费!

until循环

until基础

1.基础知识

2.简单实践

3.小结

基础知识

简介

    until命令本质上与while循环一致,区别在于until走循环之前会对输入的值进行条件判断,如果不满足条件的话,才会进入到循环体中执行对应的语句,否则的话就退出循环。

until语法解析

场景:只要条件不满足,就一直循环下去
    until [ 条件判断 ]
    do
       执行语句
    done
注意:
    条件支持的样式 命令、[[ 字符串表达式 ]]、(( 数字表达式 ))
    true是一个特殊的条件,代表条件永远成立

简单实践

实践1-输出制定的范围数字

[root@localhost ~]# cat until_num_list.sh
#!/bin/bash
# 功能:until的输出5范围以内的数字
​
# 定制初始变量值
a=1
​
# 定制内容输出逻辑
until [ "${a}" -gt 5 ]
do
   echo -n "${a} "
   # 每输出一次数据,数据值+1
   a=$((a+1))
done
echo
脚本执行后效果
[root@localhost ~]# /bin/bash until_num_list.sh
1 2 3 4 5

实践2- 计算1+2+...+100 的结果

查看脚本内容
[root@localhost ~]# cat until_odd_num.sh
#!/bin/bash
# 功能:until统计数据之和
​
# 定制普通变量
all_sum=0
odd_sum=0
​
# 定制所有数据求和逻辑
i=1
until ((i>100))
do
  let all_sum+=i
  let i++
done
​
# 定制所有奇数求和逻辑
i=1
until ((i>100))
do
  let odd_sum+=i
  let i+=2
done
​
# 信息输出
echo -e "\e[31m所有数据之和: ${all_sum}\e[0m"
echo -e "\e[31m所有奇数之和: ${odd_sum}\e[0m"
​
脚本执行后效果
[root@localhost ~]# /bin/bash until_odd_num.sh
所有数据之和: 5050
所有奇数之和: 2500

嵌套案例

学习目标

这一节,我们从 基础知识、简单实践、小结 三个方面来学习。

基础知识

简介

这里的嵌套实践,与while语句的嵌套实践基本一致,只不过组合的方式发生了一些变化。常见的组合样式如下:
until嵌套until语句
    until 循环条件
    do
        until 循环条件语句
    done
until嵌套if语句
    until 循环条件
    do
        if 条件控制语句
    done    

简单实践

until嵌套until语句实践1-输出99乘法表

查看脚本内容
[root@localhost ~]# cat until_nine_table.sh
#!/bin/bash
# 功能:until打印倒序99乘法表
​
# 定制打印99乘法表的业务逻辑
# 对第一个位置的数字进行循环
num1=9
until [ ${num1} -eq 0 ]
do
    # 对第二个位置的数字进行循环
    num2=1
    until [ ${num2} -gt ${num1} ]
    do
        # 信息输出,\t\c 的目的是删除后续信息,生成的内容是固定长度
        echo -e "\e[$[RANDOM%9+31]m${num1}x${num2}=$[num1*num2]\e[0m\t\c"
        num2=$[$num2+1]
    done
    num1=$[$num1-1]
    echo # 一个子循环一行内容
done    
脚本文件执行效果
[root@localhost ~]# /bin/bash until_nine_table.sh
9x1=9   9x2=18  9x3=27  9x4=36  9x5=45  9x6=54  9x7=63  9x8=72  9x9=81
8x1=8   8x2=16  8x3=24  8x4=32  8x5=40  8x6=48  8x7=56  8x8=64
7x1=7   7x2=14  7x3=21  7x4=28  7x5=35  7x6=42  7x7=49
6x1=6   6x2=12  6x3=18  6x4=24  6x5=30  6x6=36
5x1=5   5x2=10  5x3=15  5x4=20  5x5=25
4x1=4   4x2=8   4x3=12  4x4=16
3x1=3   3x2=6   3x3=9
2x1=2   2x2=4
1x1=1

until嵌套if语句实践2-手机发送短信1次/1毛,余额低于1毛提示无法发送请充值

[root@localhost ~]# cat until_mobile_bill.sh
#!/bin/bash
# 功能:until提示收集发短信
​
# 定制普通变量
read -p "> 请输入收集话费余额(元): " mobile_bill
​
# 定制普通变量
sms_num=0
bull_count=$[$mobile_bill * 10]
until [ $bull_count -lt 0 ]
do
    sms_num=$(($sms_num+1))
    if [ $bull_count -lt 1 ];then
        echo "剩余费用不足,请充话费!"
    else
        echo "截至目前,您已发送 ${sms_num} 条短信。"
    fi
    bull_count=$(($bull_count-1))
    sleep 0.1
done
脚本执行效果
[root@localhost ~]# /bin/bash until_mobile_bill.sh
> 请输入收集话费余额(元): 1
截至目前,您已发送 1 条短信。
截至目前,您已发送 2 条短信。
截至目前,您已发送 3 条短信。
截至目前,您已发送 4 条短信。
截至目前,您已发送 5 条短信。
截至目前,您已发送 6 条短信。
截至目前,您已发送 7 条短信。
截至目前,您已发送 8 条短信。
截至目前,您已发送 9 条短信。
截至目前,您已发送 10 条短信。
剩余费用不足,请充话费!

select条件控制

基础实践

1.基础知识

2.简单实践

3.小结

基础知识

简介

    select和其他循环控制不一样,它一般用来增强交互性,它可以显示出带编号的菜单,用户输入不同的编号就可以选择不同的菜单,并执行不同的功能。
    虽然select本身就是循环,但是select的循环仅限于接收列表中的输入信息,所以在生产中,我们一般将Select 搭配 case来使用,从而实现更为复杂的菜单控制选项。
​
​
​
select 表达式是一种bash的扩展应用,动作包括:
    自动用1,2,3,4列出菜单 ( 没有echo指令,自动显示菜单)
    自动read输入选择 ( 没有 read指令,自动输入)
    赋值给变量  ( 没有赋值指令,自动输入数字后,赋值字符串给变量)

语法解读

select 变量名 in  input_list 
do 
    循环语句 
done
语法解读:
    1 select 从 input_list 获取相关的值,然后输出到一个菜单列表,元素格式如下:
        序号) 菜单条目
    2 用户输入信息的标识使用PS3 的值,默认值是#?。
        我们可以定制PS3环境变量
    3 如果用户输入菜单序号,则输出菜单内容
    4 select的退出方式有很多种
        强制退出:Ctrl+D 组合键
        普通退出:结合break方式

简单实践

实践1-语法实践

[root@localhost ~]# cat simple_select.sh
#!/bin/bash
# select语句的使用
​
# 定制select循环逻辑
echo "您喜欢的操作系统是?"
select osname in "HarmonyOS" "Linux" "Windows" "Ubuntu"
do   
    echo "您选择的操作系统是: $osname."
done
脚本执行效果
[root@localhost ~]# /bin/bash simple_select.sh
您喜欢的操作系统是?
1) HarmonyOS
2) Linux
3) Windows
4) Ubuntu
#? 5
您选择的操作系统是: .
#? 2
您选择的操作系统是: Linux.
#?                      # 使用Ctrl + D 方式退出循环

实践2-定制信息+优雅退出

[root@localhost ~]# cat simple_select.sh
#!/bin/bash
# select语句的使用
​
# 定制普通环境变量
PS3='请选择菜单序号: '
​
# 定制select循环逻辑
echo "您喜欢的操作系统是?"
select osname in "HarmonyOS" "Linux" "Windows" "Ubuntu"
do   
    echo "您选择的操作系统是: $osname."
    break  
done
脚本执行效果
[root@localhost ~]# /bin/bash simple_select.sh
您喜欢的操作系统是?
1) HarmonyOS
2) Linux
3) Windows
4) Ubuntu
请选择菜单序号: 1
您选择的操作系统是: HarmonyOS.
[root@localhost ~]# 

###

case实践

实践3-整合case实践

查看脚本内容
[root@localhost ~]# cat simple_select_case.sh
#!/bin/bash
# select语句的使用
​
# 定制普通环境变量
PS3='请选择菜单序号: '
​
# 定制select循环逻辑
echo "您喜欢的操作系统是?"
select osname in "HarmonyOS" "Linux" "Windows" "Ubuntu"
do
    echo "-----------------------------"
    case $osname in
        "HarmonyOS")
            echo -e "\e[31m$osname 是华为推出的操作系统。\e[0m"
            break;;
        "Linux")
            echo -e "\e[31m$osname 是比较常用的操作系统。\e[0m"
            break;;
        "Windows")
            echo -e "\e[31m$osname 是一个桌面的操作系统。\e[0m"
            break;;
        "Ubuntu")
            echo -e "\e[31m$osname 是一个很好的操作系统。\e[0m"
            break;;
        *)
            echo -e "\e[31m您输入的是无效信息,再来一次!!!\e[0m"
            break;;
    esac  
done
[root@localhost ~]# /bin/bash simple_select_case.sh
您喜欢的操作系统是?
1) HarmonyOS
2) Linux
3) Windows
4) Ubuntu
请选择菜单序号: 1
-----------------------------
HarmonyOS 是华为推出的一款面向万物互联的全场景分布式操作系统。
[root@localhost ~]# /bin/bash simple_select_case.sh
您喜欢的操作系统是?
1) HarmonyOS
2) Linux
3) Windows
4) Ubuntu
请选择菜单序号: 5
-----------------------------
您输入的是无效信息,再来一次!!!

软件部署

select定制安装软件的界面功能

[root@localhost ~]# cat soft_install_select.sh
#!/bin/bash
# 功能:定制软件应用的部署功能
# 版本:v0.1
# 作者:书记
# 联系:www.superopsmsb.com
​
# 定制普通环境变量
PS3='请选择软件序号: '
​
# 定制数组变量
soft_name=(Nginx Apache Tomcat)
# 定制select循环逻辑
echo "您需要安装的Web软件是?"
select soft in ${soft_name[@]}
do
    echo "-----------------------------"
    case $soft in
        "Nginx")
            echo -e "\e[31m开始安装 $soft 软件环境...\e[0m"
            break;;
        "Apache")
            echo -e "\e[31m开始安装 $soft 软件环境...\e[0m"
            break;;
        "Tomcat")
            echo -e "\e[31m开始安装 $soft 软件环境...\e[0m"
            break;;
        *)
            echo -e "\e[31m您输入的是无效信息,再来一次!!!\e[0m"
            break;;
    esac  
done
脚本执行效果
[root@localhost ~]# /bin/bash soft_install_select.sh
您需要安装的Web软件是?
1) Nginx
2) Apache
3) Tomcat
请选择软件序号: 1
-----------------------------
开始安装 Nginx 软件环境...
[root@localhost ~]# /bin/bash soft_install_select.sh
您需要安装的Web软件是?
1) Nginx
2) Apache
3) Tomcat
请选择软件序号: 4
-----------------------------
您输入的是无效信息,再来一次!!!

##

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值