shell编程之——case和循环语句(for循环,while循环until循环语句的详解continue,break解释)——shell函数与数组的使用方法!

it2023-05-21  75

这里写目录标题

一、case多分支语句1.1、case语句的结构1.2、case语句的实例1.2.1、创建一个判断输入类型的脚本1.2.2、判断学生成绩的优良 二、循环语句2.1、for循环2.1.1、for语句结构2.1.2、使用for批量添加用户2.1.3、shell中let命令2.1.4、计算1-10偶数/奇数的和 2.2、while循环语句2.2.1、while语句结构2.2.2、while语句应用示例2.2.3、while死循环2.2.4、使用while批量添加用户2.2.5、猜商品价格游戏 2.3、continue和break2.3.1、continue2.3.2、break2.3.3、break和continue的区别 2.4、untli循环语句2.4.1、until语句的结构2.4.2、until语句应用12.4.3、until语句应用2 三、shell函数3.1、shell函数概述3.2、shell函数定义3.3、调用函数的方法3.4、shell函数应用13.5、shell函数应用2 四、shell数组4.1、数组应用场景4.2、数组定义方法4.3、数组包括的数据类型与数组操作4.3.1、数组包括的数据类型4.3.2、数组操作4.4、求数组最大值

一、case多分支语句

1.1、case语句的结构

针对变量的不同取值,分别执行不同的命令序列这种情况与多分支的if语句非常相似,只不过if语句需要判断多个不同的条件,而case语句指示判断一个变量的不同取值 格式: case 变量值 in 模式1) 命令序列1 ;; 模式2) 命令序列2 ;; .... *) 默认命令序列 esac

例:

实例: case 控制指令 in start) 启动XX服务 ;; stop) 停止XX服务 ;; .... *) 显示服务脚本的用法 esac

1.2、case语句的实例

1.2.1、创建一个判断输入类型的脚本

提示用户输入一个字符判断出该字符是字母,数字或者其他字符 [root@localhost opt]# vim panduan.sh #!/bin/bash read -p "请输入一个字符:" aa case "$aa" in [0-9]) echo "你输入的是数字" ;; [a-z]|[A-Z]) echo "你输入的是字母" ;; *) echo "你输入的是符号" esac ~ [root@localhost opt]# chmod +x panduan.sh [root@localhost opt]# ./panduan.sh 请输入一个字符:3 你输入的是数字 [root@localhost opt]# ./panduan.sh 请输入一个字符:e 你输入的是字母 [root@localhost opt]# ./panduan.sh 请输入一个字符:# 你输入的是符号

1.2.2、判断学生成绩的优良

成绩0-100分

0-59分:不及格

60-74:及格

75-84:良好

85-100:优秀

[root@localhost opt]# vim chengji.sh #!/bin/bash read -p "请输入你的成绩:" aa case "$aa" in #[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]) [1-5][0-9]|[0-9]) echo "你的成绩不合格" ;; 6[0-9]|7[0-4]) echo "你的成绩合格" ;; 7[5-9]|8[0-4]) echo "你的成绩良好" ;; 8[5-9]|9[0-9]|100) echo "你的成绩优秀" ;; *) echo "输入有误" esac ~ [root@localhost opt]# ./chengji.sh 请输入你的成绩:0 你的成绩不合格 [root@localhost opt]# ./chengji.sh 请输入你的成绩:59 你的成绩不合格 [root@localhost opt]# ./chengji.sh 请输入你的成绩:60 你的成绩合格 [root@localhost opt]# ./chengji.sh 请输入你的成绩:74 你的成绩合格 [root@localhost opt]# ./chengji.sh 请输入你的成绩:75 你的成绩良好 [root@localhost opt]# ./chengji.sh 请输入你的成绩:84 你的成绩良好 [root@localhost opt]# ./chengji.sh 请输入你的成绩:85 你的成绩优秀 [root@localhost opt]# ./chengji.sh 请输入你的成绩:100 你的成绩优秀 [root@localhost opt]# ./chengji.sh 请输入你的成绩:101 输入有误 [root@localhost opt]# ./chengji.sh 请输入你的成绩:-1 输入有误

二、循环语句

2.1、for循环

2.1.1、for语句结构

读取不同的变量值,用来逐个执行同一组命令 语句结构 for 变量名 in 取值列表 do 命令序列 done 语句结构举例 for 收件人 in 邮件地址列表 do 发送邮件 done

2.1.2、使用for批量添加用户

用户名存放在users.txt文件中,每行一个初始密码均设为123456 [root@localhost opt]# vim user.txt zhangsan lisi wangermazi zhaoliu tianji wangba [root@localhost opt]# vim useradd.sh #!/bin/bash Lists=$(cat /opt/user.txt) for bb in $Lists do useradd $bb echo "123456" | passwd --stdin $bb echo "$bb添加成功" done [root@localhost opt]# chmod +x useradd.sh [root@localhost opt]# ./useradd.sh Changing password for user zhangsan. passwd: all authentication tokens updated successfully. zhangsan添加成功 useradd: warning: the home directory already exists. Not copying any file from skel directory into it. Creating mailbox file: File exists Changing password for user lisi. passwd: all authentication tokens updated successfully. lisi添加成功 Changing password for user wangermazi. passwd: all authentication tokens updated successfully. wangermazi添加成功 Changing password for user zhaoliu. passwd: all authentication tokens updated successfully. zhaoliu添加成功 Changing password for user tianji. passwd: all authentication tokens updated successfully. tianji添加成功 Changing password for user wangba. passwd: all authentication tokens updated successfully. wangba添加成功 [root@localhost opt]# cat /etc/passwd | grep "bash" root:x:0:0:root:/root:/bin/bash dd:x:1000:1000:cn-tangzheng:/home/dd:/bin/bash zhangsan:x:1001:1001::/home/zhangsan:/bin/bash lisi:x:1002:1002::/home/lisi:/bin/bash wangermazi:x:1003:1003::/home/wangermazi:/bin/bash zhaoliu:x:1004:1004::/home/zhaoliu:/bin/bash tianji:x:1005:1005::/home/tianji:/bin/bash wangba:x:1006:1006::/home/wangba:/bin/bash 脚本可以适当修改优化:如 echo "123456" | passwd --stdin $bb &> /dev/null 批量删除用户:在刚刚的基础上修改 [root@localhost opt]# vim useradd.sh #!/bin/bash Lists=$(cat /opt/user.txt) for bb in $Lists do userdel -r $bb '-r 删除家目录' #echo "123456" | passwd --stdin $bb &> /dev/null echo "$bb删除成功" done [root@localhost opt]# ./useradd.sh zhangsan删除成功 lisi删除成功 wangermazi删除成功 zhaoliu删除成功 tianji删除成功 wangba删除成功 [root@localhost opt]# cat /etc/passwd | grep "bash" root:x:0:0:root:/root:/bin/bash dd:x:1000:1000:cn-tangzheng:/home/cn-tangzheng:/bin/bash

2.1.3、shell中let命令

let 对整数进行数学运算let和双小括号 (( )) 一样,let 命令也只能进行整数运算,不能对小数(浮点数)或者字符串进行运算。 语法格式 let 表达式 或 let "表达式"let '表达式' 以上方式都等价于 ((表达式)) 当表达式中含有 Shell 特殊字符(例如 |)时,需要用双引号" "或者单引号’ '将表达式包围起来。和 (( )) 类似,let 命令也支持一次性计算多个表达式,并且以最后一个表达式的值作为整个 let 命令的执行结果。

2.1.4、计算1-10偶数/奇数的和

方式一:计算偶数的和 #!/bin/bash sum=0 for((i=0;i<=10;i+=2)) do let sum+=$i done echo "总和为:$sum" 方式一:计算奇数的和 #!/bin/bash sum=0 for((i=1;i<=10;i+=2)) do let sum+=$i done echo "总和为:$sum" 方式二:求偶数和 #!/bin/bash sum=0 for((i=0;i<=10;i+=2)) do if [ `expr $i % 2` -eq 0 ] then let sum+=$i fi done echo "总和为:$sum" 方式二:求奇数和 #!/bin/bash sum=0 for((i=1;i<=10;i+=2)) do if [ `expr $i % 2` -eq 1 ] then let sum+=$i fi done echo "总和为:$sum"

2.2、while循环语句

2.2.1、while语句结构

重复测试某个条件,只要条件成立则反复执行 语句结构 while 条件测试操作 do 命令序列 done 语句结构示例 while 未猜中正确的价格 do 反复猜测商品价格 done

2.2.2、while语句应用示例

使用while循环语句输出1-10数字 #!/bin/bash i=0 while [ $i -le 5 ] do echo "$i" let i++ done [root@localhost opt]# . cccc.sh 0 1 2 3 4 5

2.2.3、while死循环

while true:死循环有时候也有奇效,可与用户交互 #!/bin/bash while true do read -p "请输入yes退出:" KEY if [ $KEY = yes ] then break fi done echo "正常退出" [root@localhost opt]# ./sixunhuan.sh 请输入yes退出:no 请输入yes退出:1 请输入yes退出:d 请输入yes退出:! 请输入yes退出:a 请输入yes退出:yes 正常退出

2.2.4、使用while批量添加用户

用户名称以stu开头,按数字顺序进行编号一共添加20个用户,即stu1,stu2…stu20初始密码设置为 #!/bin/bash i=0 while [ $i -le 19 ] do let i++ useradd stu$i echo "123456" | passwd --stdin stu$i &> /dev/null echo "stu$i添加成功" done echo "添加完毕" [root@localhost opt]# ./useradd.sh stu1添加成功 stu2添加成功 stu3添加成功 stu4添加成功 stu5添加成功 stu6添加成功 stu7添加成功 stu8添加成功 stu9添加成功 stu10添加成功 stu11添加成功 stu12添加成功 stu13添加成功 stu14添加成功 stu15添加成功 stu16添加成功 stu17添加成功 stu18添加成功 stu19添加成功 stu20添加成功 添加完毕

2.2.5、猜商品价格游戏

通过变量RANDOM获得随机数提示用户猜测并记录次数,猜中后退出循环 #!/bin/bash A=`expr $RANDOM % 1000` i=0 echo "商品的实际价格为0-999之间,猜猜看是多少?" read -p "请输入你猜测的价格数目:" num while [ $num -le 999 ] && [ $num -ge 1 ] do let i++ if [ $num -eq $A ] then echo "恭喜你答对了,实际价格是$A" echo "你一共猜测了$i 次" exit 0 elif [ $num -lt $A ] then echo "太低了" read -p "请输入你猜测的价格数目:" num else echo "太高了" read -p "请输入你猜测的价格数目:" num fi done

2.3、continue和break

2.3.1、continue

命令格式: continue n

n 表示循环的层数:         如果省略 n,则表示 continue 只对当前层次的循环语句有效,遇到 continue 会跳过本次循环,忽略本次循环的剩余代码,直接进入下一次循环。         如果带上 n,比如 n 的值为 2,那么 continue 对内层和外层循环语句都有效,不但内层会跳过本次循环,外层也会跳过本次循环,其效果相当于内层循环和外层循环同时执行了不带 n 的 continue。这么说可能有点难以理解,稍后我们通过代码来演示。 continue 关键字也通常和 if 语句一起使用,即满足条件时便跳出循环。

2.3.2、break

命令格式: break n

        n 表示跳出循环的层数,如果省略 n,则表示跳出当前的整个循环。         break 关键字通常和 if 语句一起使用,即满足条件时便跳出循环。

2.3.3、break和continue的区别

break 用来结束所有循环,循环语句不再有执行的机会;continue 用来结束本次循环,直接跳到下一次循环,如果循环条件成立,还会继续循环。

2.4、untli循环语句

2.4.1、until语句的结构

重复测试某个条件,只要条件不成立则反复执行 until 条件测试操作 do 命令序列 done while 未超过10 do 数字依次增加 done

2.4.2、until语句应用1

计算1–50的和 通过循环累加的方式计算1–50的和 #!/bin/bash i=1 S=0 until [ $i -eq 51 ] do let S+=$i let i++ done echo "$S" [root@localhost opt]# ./jisuan.sh 1275

2.4.3、until语句应用2

为指定用户发送在线消息 1、若指定用户不在线(未登陆系统),则每10分钟(实验中为了测试效果,可改为3s)试一次,直至用户登录系统后再发送信息 2、用户名与消息通过为止参数传递给脚本 #!/bin/bash username=$1 #判断格式参数是否为空 if [ $# -lt 1 ] then echo "Usage:`basename $0` <username> [<message>]" exit 1 fi #判断账号是否存在 if grep "^$username:" /etc/passwd &> /dev/nell;then : else echo "用户不存在" exit 2 fi #判断用户是否在线 until who | grep "$username" &> /dev/null do echo "用户不在线,正在尝试连接" sleep 3 done mes=$* echo "$mes" | write "$username" [root@localhost opt]# ./mes.sh Usage:mes.sh <username> [<message>] [root@localhost opt]# ./mes.sh wangwu 用户不存在 [root@localhost opt]# ./mes.sh stu1 用户不在线,正在尝试连接 用户不在线,正在尝试连接

三、shell函数

3.1、shell函数概述

shell一个非常重要的特性是它可作为一种编程语言来使用。因为shell是一个解释器,所以它不能对为它编写的程序进行编译,而是在每次从磁盘加载这些程序时对它们进行解释。而程序的加载和解释都是非常耗时的。针对此问题,许多shell(如BourneAgainShell)都包含shell函数,shell把这些函数放在内存中,这样每次需要执行它们时就不必再从磁盘读入。shell还以一种内部格式来存放这些函数,这样就不必耗费大量的时间来解释它们shell函数将命令序列按格式写在一起可以方便重复使用命令序列

3.2、shell函数定义

return返回的是状态码,需要使用$?调取echo 返回的是值,使用变量调用传参:指位置变量可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)

3.3、调用函数的方法

函数名 [参数1($1) ] [ 参数2($2) ]在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…10不能获取第十个参数,获取第十个参数需要{10}。当n>=10时,需要使用${n}来获取参数。

3.4、shell函数应用1

两个数字求和 1、通过sum(){}定义函数 2、使用read命令交互输入两个数并求和 #!/bin/bash #sum=0 function A (){ read -p "请输入第一个数字:" B read -p "请输入第二个数字:" C sum=`expr $B + $C` echo "$B + $C = $sum" return 3 } #echo $sum A $B $C [root@localhost opt]# ./han.sh 请输入第一个数字:4 请输入第二个数字:2 4 + 2 = 6 [root@localhost opt]# echo $? 3 [root@localhost opt]# echo $? 0

3.5、shell函数应用2

编写登录系统后便可使用的自定义函数 1、编辑用户自定义函数文件/root/function 2、在当前shell中加载可执行的函数文件/root/function 3、在~/.bashrc文件中添加source /root/function命令

四、shell数组

4.1、数组应用场景

获取数组长度 使用for循环获取具体信息,使用下标或索引标记数组中数据的位置 可以存放多种数据,如:整型,长整形,浮点型(单精度,双精度),字符串等获取元素长度遍历元素元素切片元素替换元素删除。。。

4.2、数组定义方法

方法一: 基本格式 数组名=(value0 value1 value2...) 例如 ABC=(11 22 33...) 方法二: 基本格式 数组名=[0]=value [1]=value [2]=value...) 例如 ABC=[0]=11 [1]=22 [2]=33...) 方法三:数组元素之间使用空格隔开 基本格式 列表名=“value0 value1 value2” 数组名=($列表名) 例如 AAA=“11 22 33...” ABC=($列表名) 方法四: 基本格式 数组名[0]=“value” 数组名[1]=“value” 数组名[2]=“value” ... 例如 AAA[0]=“11” AAA[1]=“22” AAA[2]=“33” ...

4.3、数组包括的数据类型与数组操作

4.3.1、数组包括的数据类型

数值类型字符类型

4.3.2、数组操作

获取数组长度 基本格式 ${#数组名[@/*]} 例如 [root@localhost opt]# abc=(10 20 30) [root@localhost opt]# echo ${abc[*]} 10 20 30 [root@localhost opt]# echo ${#abc[*]} 3 读取某下标赋值 基本格式 ${数组名[下标]} 例如 [root@localhost opt]# echo ${abc[1]} 20 [root@localhost opt]# echo ${abc[0]} 10 [root@localhost opt]# echo ${abc[1]} 20 [root@localhost opt]# echo ${abc[2]} 30

4.4、求数组最大值

#!/bin/bash for ((i=1;i<=5;i++));do read -p "请输入第$i个数字:" num abc[$i-1]=$num done max=${abc[0]} for ((k=1;k<=${#abc[*]}-1;k++));do if [ $max -lt ${abc[$k]} ];then max=${abc[$k]} fi done echo "最大值是:$max" [root@localhost opt]# chmod +x max.sh [root@localhost opt]# ./max.sh 请输入第1个数字:2 请输入第2个数字:3 请输入第3个数字:66 请输入第4个数字:33 请输入第5个数字:111 最大值是:111
最新回复(0)