引言
今天我们来看看循环语句的应用以及shell函数和数组
一、for语句的结构
- 读取不同的变量值,用来逐个执行同一组命令
for循环经常使用在已经知道要进行多少次循环的场景
for 变量名 in 取值列表 > for 收件人 in 邮件地址列表
do > do
命令序列 > 发送邮件
done > done
循环出1到6之间的整数
查看0…50的偶数
i++ / i=i+1 一个意思
批量创建用户并修改密码
批量删除用户
根据IP地址列表检查主机的状态
设置密码 输错三次进行警告
概率小实验
嵌套循环 星星的格式
9*9乘法表
随机生成密码
二、while循环
- 重复测试某个条件,只要在条件成立则反复执行
while 条件测试操作
do
命令序列
done
1.continue和break的区别
- continue 终止每次循环中的命令,但是不会完全终止命令
- break 跳出单个循环 ,仅在"for" “while” 或"until"循环中有意义
(1)定义一个变量 猜大小
(2)使用while循环创建用户和密码
(3)猜数字小实验
(4)商店购物
#!/bin/bash
i=1
sum=0
while [ $i -le 5 ]
do
echo "本公主今天宠爱第$i家商店呢"
read -p "是否进入看看(yes/no)" doing
while [ $doing = "yes" ]
do
echo "1:衣服 ¥2000"
echo "2:鞋子 ¥5000"
echo "3:帽子 ¥1000"
echo "4:裤子 ¥3000"
read -p "请选择需要购买的商品序列号:" num
case $num in
1)
echo "衣服购买成功!"
expr $[ sum+=2000 ] &> /dev/null
;;
2)
echo "鞋子购买成功!"
expr $[ sum+=5000 ] &> /dev/null
;;
3)
echo "帽子购买成功!"
expr $[ sum+=1000 ] &> /dev/null
;;
*)
echo "裤子购买成功!"
expr $[ sum+=2000 ] &> /dev/null
;;
esac
read -p "是否继续进行购买(yes/no)" doing
done
let i++
if [ $doing = "no" ]
then break
fi
done
echo "今天您的购物总价为:$sum"
三. until 循环语句结构
用法: 重复测试某个条件,只要条件不成立则反复执行
只要while后面的命令退出状态为0,while循环就一直执行下去,until命令与while命令相似,唯一的区别在于,只要until后面的命令退出不为0,until循环就一直执行下去,也就是说,使用until语句重复执行一段代码直到条件为真为止,与while类似
格式:
until 条件测试操作
do
命令序列
done
1.计算0-50的和
[root@zhang until]# vim 50.sh
#!/bin/bash
i=1 //定义变量i=1
sum=0
until [ $i -eq 51 ] //$i等于51时停止执行
do
sum+1=i //sum=sum+i
let i++ //每次循环i+1
done
echo "$sum" //打印结果 $sum
四、Shell函数
- 将命令序列按格式写在一起
- 可方便重复使用命令序列
1.函数基本格式
[function] 函数名(){
命令序列
[return x] #使用return或exit可以显示的结束函数
}
或者 #也可以省略掉[function],它表示该函数的功能
函数名() { #函数名后面()是没有内容的
命令序列 #我们执行的命令内容放在{}里面
}
- 函数定义完之后并不会自动执行,需要调用才行
- 好处在于可以写一段功能代码作为函数,有需要就直接调用定义的时候哪怕出现语法错误也没关系,不调用就不会报错
- 当然我们写函数最终目的还是为了调用,为了实现某个功能块。
2.函数返回值
return表示退出函数并返回一个退出值,脚本中可以用$? 变量显示该值使用原则
- 函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码
- 退出状态码必须是0~255,超出时值将为256取余
3.函数应用示例
4.一键部署yum库
6.return的用法
7.求和
8.函数的传参
- 在Shell中,调用函数时可以向其传递参数。在函数体内部,通过$n的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数…即使用位置参数来实现参数传递。
列:1.通过位置变量进行求和
9.函数的作用范围
- 函数在shell脚本中仅在当前shell环境中有效
- shell脚本中变量默认全局有效
- 将变量限定在函数内部使用local命令
列:局部变量和全局变量的区别
但是注意了如果没有local i这句话时,i是全局变量,当他为全局变量的时候,他是从上往下执行的,系统只承认第一个定义的i的值,以后所有的i不管在定义为什么都是第一个定义的值。
没有local的话 他就是一个全局变量
10.求1到6的阶乘
11.判断是否为文件
判断该文件是否问文件 如果是文件就显示80 否则则显示40
-f代表是不是文件
五、数组的使用方法
1.数组的定义
数组是存放相同类型数据的集合,在内存中开辟了连续的空间,通常配合循环使用
2.数组的分类
- 普通数组:不需要声明直接定义,下标索引只能是整数
- 关联数组:需要用declare -A声明否则系统不识别,索引可以是字符串
3.数组的定义方式
(30 20 10 60 50 40)
0 1 2 3 4 5
- 第一种:直接把要加入数组的元素用小括号括起来,中间空格分开
num=(11 22 33 44)
${#num}显示字符串长度
数组名=(value0 value1 value2)
- 第二种:直接把要加入数组的元素用小括号括起来,中间用空格分开
num=([0]=55 [1]=66 [2]=77 [4]=88)
数组名=([0]=value [1]=value [2]=value [4]=value…)
- 第三种:先把要记入数组的元素全部先赋值给一个变量,然后引用这个变量加入到数组
list=“11 12 13 14”
num=($list)
4.元素切片
5.定义某一个元素
[root@localhost ~]# fruit[0]=pear
[root@localhost ~]#
[root@localhost ~]# echo ${fruit[*]}
pear banana orange
6.元素替换
定义或替换某一个元素
[root@localhost ~]# fruit[0]=pear
[root@localhost ~]#
[root@localhost ~]# echo ${fruit[*]}
pear banana orange
[root@localhost ~]# echo ${fruit[*]/banana/ba} //临时替换
pear ba orange
[root@localhost ~]# echo ${fruit[*]}
pear banana orange
7.元素删除
[root@localhost ~]# unset fruit[0]
[root@localhost ~]#
[root@localhost ~]# declare -a | grep fruit
declare -a fruit='([1]="banana" [2]="orange")'
8.数组删除
[root@localhost ~]# unset arr
9.冒泡排序
类似气泡上涌的动作,会将数据在数组中从小到大或者从大到小不断的向前移动。
#!/bin/bash
array=(90 70 80 100 30 66) #定义数组
echo "old_array:${array[*]}" #1.代表排序前的数组
lt=${#array[*]} #数组长度
#定义比较轮数,比较轮数为数组长度-1,从1开始
for ((i=1;i<=$lt;i++))
#当下标为0时for ((i=0;i<$lt;i++))
do
#确定比较元素的位置,比较相邻的两个元素,较大的数往后放,在比较次数谁比较轮数而减少
for ((j=0;j<$lt-i;j++))
do
#定义第一个元素的值
first=${array[$j]}
#定义第二个元素的值
k=$[$j+1]
second=${array[$k]}
#如果第一个元素比第二个元素大,就互换
if [ $first -gt $second ];then
#把第一个元素的值保存到临时变量中
temp=$first
#把第二个元素赋值给第一个元素
array[$j]=$second
#把临时变量赋值给第二个元素
array[$k]=$temp
fi
done
done
echo "new_array:${array[*]}"
减一是因为每次我对比完成之后,都会确定一个本轮比较的最大值,下次就不需要在比较了
六、总结
- for语句的结构
- while语句的结构
- until语句的结构
- Shell函数定义方法
- 数组使用方法