shell脚本编程(八)

shell脚本编程(七)https://blog.csdn.net/xiaochenXIHUA/article/details/156889172?spm=1001.2014.3001.5501

一、while循环语句

1.1、while循环语句

bash 复制代码
#while循环语句的语法
while expr        #执行expr
do                #若expr的退出状态为0,则进入循环,否则退出while循环
    commands      #执行语句块
done              #循环结束标志,返回循环顶部

先执行expr,若其退出状态为0,就执行循环体,执行到关键字【done】后,就回到循环顶部,while命令再次检查expr的退出状态。以此类推,循环将一直继续下去,直到exr的退出状态为非0为止。执行流程图如下:

|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| 序号 | 说明 |
| 1 | while循环语句也称前测试循环语句,它的循环重复执行次数,是利用一个条件控制是否继续重复执行这个语句。while语句与for循环语句相比,无论是语法还是执行的流程,都比较简明易懂。 |
| 2 | while循环语句之所以命名为前测循环,是因为它要先判断此循环的条件是否成立,然后才作重复执行的操作。也就是说,while循环语句执行的过程是:先判断expression的退出状态,若退出状态为0,则执行循环体,执行到关键字done后,就回到循环的顶部,进行下一次循环,否则退出循环执行done后的命令。 |
| 3 | 为了避免死循环,必须保证在循环体中包含循环出口条件,即存在expression的退出状态为非0的情况。 |
[while循环的注意事项]

1.1.1、while循环示例一

bash 复制代码
#while循环语句示例
vi while-guess-number.sh

#【while-guess-number.sh】文件的完整内容
#!/bin/bash
#filename:while-guess-number.sh
#$RANDOM是系统随机数的环境变量,模100运算用于生成1-100的随机整数
randomnum=$((RANDOM%100))
#使用永真循环(while :),条件退出(break)的方式是接收用户的猜测并进行判断
while :
do
        read -p "请输入你要猜的数字(0-99):" answer
        if [ $answer -lt $randomnum  ];then
                echo "你输入的【$answer】小于随机数,请重新输入"
        elif ((answer>randomnum));then
                echo "你输入的【$answer】大于随机数,请重新输入"
        elif [[ $answer -eq $randomnum ]];then
                echo "恭喜你,猜到了随机数【$randomnum】"
                break
        fi
done


#执行脚本
bash while-guess-number.sh

1.1.2、while循环示例二

读取文件的内容

bash 复制代码
#while循环示例二
vi while-readfile.sh

#【while-readfile.sh】文件的完整内容
#!/bin/bash
#filename:while-readfile.sh
file=/etc/yum.repos.d/epel.repo
oldifs=$IFS
while IFS= read -r line
do
        echo $line
done < $file
IFS=$oldifs


#执行脚本
bash while-readfile.sh

1.1.3、while循环示例三

读取文件中每行的多个内容

bash 复制代码
#while循环示例三
vi while-readfile2.sh

#【while-readfile2.sh】文件的完整内容
#!/bin/bash
#filename:while-readfile2.sh
oldIFS=$IFS
#设置默认的IFS分隔符为冒号,且定义了多个变量
while IFS=: read -r user enpass uid gid desc home shell
do
        #只显示UID大于等于500的内容
        [ $uid -ge 500 ] && echo "User $user $enpass ($uid) $gid $desc assigned "$home" home directory with $shell shell."
done < /etc/passwd
IFS=$oldIFS


#执行脚本
bash while-readfile2.sh

1.2、计数器控制的while循环

假定已经准确知道要输入的数据或字符串的数目,在这种情况下可采用计数器控制的while循环结构来处理。

bash 复制代码
#计数器控制的while循环结构
counter=1
while expression
do
    command
    ...
    let command to operate counter
    command
    ...
done
    
bash 复制代码
#计数器控制的while循环
vi while-counter.sh

#【while-counter.sh】文件的完整内容
#!/bin/bash
#filename:while-counter.sh
count=1
while [ $count -lt 12 ];do
        echo $count
        let count+=1
done


#执行脚本
bash while-counter.sh

1.3、结束标记控制的while循环

在linux shell编程中很多时候不知道读入数据的个数,但是可以设置一个特殊的数据来结束while循环,该特殊数据值称为结束标记,其通过提示用户输入特殊字符或数字来操作。当用户输入该标记后结束while循环,执行done后的命令。

bash 复制代码
#结束标记控制的while循环结构
read variable
while [[ $variable != flag ]]
do
    read variable
done
bash 复制代码
#结束标记控制的while循环示例
vi while-endflag.sh

#【while-endflag.sh】文件的完整内容
#!/bin/bash
#filename:while-endflag.sh
echo "请输入:"
read var
while [[ $var != ok ]];do
        echo "当前输入的内容是【$var】"
        read -p "(可输入 ok 结束)请输入:" var
done


#执行脚本
bash while-endflag.sh

1.4、标志控制的while循环

标志控制的while循环使用用户输入的标志的值来控制循环的结束,这样就避免了用户不知道循环结束标记的麻烦。

bash 复制代码
#标志控制的while循环语法
signal=0

while ((signal != 1))
do
    ...
    if expression
    then
        signal=1
    fi
    ...
done
bash 复制代码
#标志控制的while循环示例
vi while-flag2.sh

#【while-flag2.sh】文件的完整内容
#!/bin/bash
#filename:while-flag2.sh

flag=true
read -p "请输入需要计算的最大数字:" inputnum
count=0
sum=0
while [[ $flag != false ]];do
        ((++count))
        let sum+=count
        echo "计算【$count】次后的总数是【$sum】"
        if ((count==inputnum));then
                flag=false
        fi
done
echo "从【1】到【$inputnum】累加后的总数是【$sum】"


#执行脚本
bash while-flag2.sh

二、until循环语句

2.1、until循环语句

bash 复制代码
#until循环语句
until expr        #执行expr
do                #若expr的退出状态非0,则进入循环,否则退出until
    commands      #循环体
done              #循环结束标志,返回循环顶部

在执行while循环时,只要是expr的退出状态为0将一直执行循环体。until命令和while命令类似,但区别是until循环中的expr的退出状态不为0时循环体将一直执行下去,直到退出状态为0时退出循环。

bash 复制代码
#until循环语句示例
vi until.sh

#【until.sh】文件的完整内容
#!/bin/bash
#filename:until.sh
read -p "请输入需要测试是否畅通的IP地址:" ipadd
until ping -c 1 $ipadd >/dev/null 2>&1
do
        sleep 60
done
ssh $ipadd


#测试脚本
bash until.sh

2.2、exit和sleep

bash 复制代码
#exit命令
exit n

#sleep命令
sleep n

【exit】命令用于退出脚本或当前进程【n】是一个从0到255的整数,0表示成功退出,非零表示遇到某种失败而非正常退出。该整数被保存在状态变量【$?】中。

【sleep n】表示暂停几秒钟。

bash 复制代码
#exit与sleep示例
vi until-user-exist-online.sh

#【until-user-exist-online.sh】文件的完整内容
#!/bin/bash
#filename:until-user-exist-online.sh
username=$1
#判断参数是否小于1,小于则给出使用提示
if [ $# -lt 1 ];then
        echo "用法:`basename $0` <username> [<message>]"
        exit 1
fi


#判断当前输入的用户是否在系统中
if grep "^$username:" /etc/passwd >/dev/null
then
        echo "【$username】用户存在"
else
        echo "【$username】用户不存在系统中"
        exit 2
fi

until who|grep "$username" > /dev/null;do
        echo "【$username】用户目前没有登录"
        sleep 5
done


#执行脚本
bash until-user-exist-online.sh
bash until-user-exist-online.sh coffeemilk

三、循环与菜单

3.1、使用while配合case实现菜单

一般情况下可以使用while循环配合case实现循环菜单;而Bash提供了专门的select 循环实现:

《1》select循环主要用于创建菜单;

《2》select是个无限循环:

①通常要配合case 语句处理不同的选单及退出;

②select循环的退出【ctrl+c 强制退出】【直接在循环体内用break命令退出】【用exit命令终止脚本】。

bash 复制代码
#循环与菜单示例
vi while-menu.sh

#【while-menu.sh】文件的完整内容
#!/bin/bash
#filename:while-menu.sh

readonly str="你选择了"
while true;do
        echo "=======script language======"
        echo "1) bash"
        echo "2) perl"
        echo "3) python"
        echo "4) ruby"
        echo "5) I don't konw!(quit)"
        read -p "你最喜欢哪种脚本语言?" lang
        case $lang in
                1) echo "$str【bash】";;
                2) echo "$str【perl】";;
                3) echo "$str【python】";;
                4) echo "$str【ruby】";;
                5) exit
        esac
done


#执行脚本
bash while-menu.sh

3.2、循环结构select

bash 复制代码
#循环结构select语法
select variable in list
do                     #循环开始的标志
    commands           #循环变量每取一次值,循环体就执行一遍
done                   #循环结束的标志

|--------|-----------------------------------------------|
| 序号 | 说明 |
| 1 | select 循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,等待用户输入 |
| 2 | 菜单项的间隔符由环境变量IFS决定 |
| 3 | 用于引导用户输入的提示信息存放在环境变量PS3中 |
| 4 | 用户直接输入回车将重新显示菜单 |
| 5 | 与for循环类似,省略【in list】时等价于【in "$*"】 |
| 6 | 用户输入菜单列表中的某个数字,执行相应的命令 |
| 7 | 用户的输入被保存在内置变量REPLY中 |
| ||
| select与case: 《1》select是个无限循环,因此要记住用break命令退出循环,或用exit命令终止脚本。也可以按【ctrl+c】退出循环。 《2》select经常与case联合使用; 《3》与for循环类似,可以省略【in list】,是吃使用位置参量。 ||
[循环结构select说明]

3.2.1、select示例一

bash 复制代码
#循环结构select示例一
vi select1.sh

#【select1.sh】文件的完整内容
#!/bin/bash
#filename:select1.sh
clear
PS3="你最喜欢哪种脚本语言?"
select s in bash perl python ruby quit
do
        case $s in
                bash|perl|python|rubu)
                        echo "你选择了【$s】";;
                quit)
                        exit;;
                *)
                        echo "你选择错误,请重试";;
        esac
done


#执行脚本
bash select1.sh

3.2.2、select示例二

bash 复制代码
#循环结构select示例二
vi select2.sh

#【select2.sh】
#!/bin/bash
#filename:select2.sh
clear
PS3="你最喜欢那款操作系统?"
oldIFS=$IFS
IFS='|'
os="Linux|Windows|FreeBSD|MacOS"
select s in $os;do
        case $REPLY in
                1|2|3|4)
                        echo "你选择的是【$s】";;
                *)
                        exit;;
        esac
done
IFS=$oldIFS


#执行脚本
bash select2.sh

3.2.3、select示例三

bash 复制代码
#循环结构select示例三
vi select3.sh


#【slect3.sh】文件的完整内容
#!/bin/bash
#filename:select3.sh
PS3="选择你想要执行的命令:"
cmd="telnet lvm2 python3 lrzsz gcc yum"
clear
select prog in $cmd quit;do
        [[ $prog == quit ]] && exit
        rpm -q $prog >/dev/null 2>&1 && echo "【$prog】已经安装,已安装的详细版本是【`rpm -q $prog`】" || echo "【$prog】未安装"
done



#执行脚本
bash select3.sh
相关推荐
A小辣椒13 小时前
TShark:Wireshark CLI 功能
linux
A小辣椒17 小时前
TShark:基础知识
linux
AlfredZhao19 小时前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao1 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5202 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩2 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言