1、for循环结构语法及实例
1.1、for循环结构语法1
for变量名in变量取值列表
do
指令……….
done
提示:此结构中“in 变量取值列表”可省略,省略时相当于in “$@”,使用for i就相当于使用for i in “$@”
1.2、for循环结构语法2
for ((exp1;exp2;exp3)); do
指令…………
done
exp1只执行一次,相当于在for里嵌了while
1.3、for循环结构基础实例
例1:for循环直接输出元素5到1的方法
#!/bin/bash
for num in 5 4 3 2 1
do
echo $num
done
例2:for循环使用大括号的方法输出元素5到1
#!/bin/bash
for num in {5..1}
do
echo $num
done
例3:for循环使用seq方法实现输出元素5到1
#!/bin/bash
for num in `seq -s " " 5 -1 1`
#这里-s指定分隔符为空格,5为第一个输出字符,-1为步长,1为最后一个字符
do
echo $num
done
例4:使用for循环进行文件批量改名,把jpg改成gif
[root@localhost test]# ls
1.jpg 2.jpg 3.jpg 4.jpg 5.jpg
[root@localhost test]# for a in `ls /root/test/`;do mv $a `echo $a|cut -d . -f1`.gif; done
[root@localhost test]# ls
1.gif 2.gif 3.gif 4.gif 5.gif
例5:for循环在/abc目录下创建文件abc-1至abc-10
#!/bin/bash
mkdir /abc && cd /abc
for a in {1..10}
do
touch abc-$a
done
例6:for循环批量创建10个普通用户abc-01至abc-10,密码设置为aaa-01至aaa-10
#!/bin/bash
for num in `seq -w 10`#说明:-w以0补充列宽
do
useradd abc-$num
echo "aaa-$num"|passwd --stdin "abc-$num"
done
例7:for循环批量创建用户密码为8位随机字符串
#先实现8位随机数的取值
[root@localhost ~]# echo $(date +%N) #%N微秒,每次数字很难相同
099765771
[root@localhost ~]# echo $RANDOM #随机函数,每次值都不同
11755
[root@localhost ~]# echo $(date +%N)$RANDOM #两个组合生成更加不同的随机数
73312156513717
[root@localhost ~]# echo $(date +%N)$RANDOM|md5sum|cut -c 1-8
#把随机数再使用md5加密,然后取8位即可
e65d36e5
#脚本创建用户随机密码实现:
#!/bin/bash
for num in `seq -w 10`
do
#注意:这里一定要定义密码的变量,不然后面echo输出的密码就不正确了。
password=$(echo $(date +%N)$RANDOM|md5sum|cut -c 1-8)
useradd abc-$num
echo "aaa-$num"|passwd --stdin "abc-$num"
echo -e "用户名:abc-$num密码:$password" >>/root/user.txt
done
一句话实现方式:
[root@localhost ~]# for num in `seq -w 10`;do password=$(echo $(date +%N)$RANDOM|md5sum|cut –c 1-8);echo -e "用户名:abc-$num密码:$password";done
用户名:abc-01密码:66e7c7ab
用户名:abc-02密码:34dd9e01
用户名:abc-03密码:9accf4e5
用户名:abc-04密码:919cad0a
用户名:abc-05密码:b2c259c0
用户名:abc-06密码:c59e255f
用户名:abc-07密码:bd8bd4f7
用户名:abc-08密码:62b9633d
用户名:abc-09密码:cac00924
用户名:abc-10密码:839317aa
例8:求出(1+2+3...+n)的总和
#!/bin/bash
sum=0
read -p "请输入一个需要从1加到多少的整数:" num
if [[ $num =~ [^0-9] ]];then
echo "输入有误,请输入大于0的整数!!!"
elif [[ $num -eq 0 ]];then
echo "输入有误,请输入大于0的整数!!!"
else
for i in $(seq 1 $num);do
sum=$[$sum+$i]
done
echo $sum
fi
分析:sum初始值为0,请输入一个数,先判断输入的是否含有除数字以外的字符,有就报错;没有判断是否为0,不为0进入for循环,i的范围为1~输入的数,每次的循环为sum=sum+i,循环结束,最后输出sum的值。
例9:计算1+3+5+.....+100所有奇数的和
#!/bin/bash
for ((i=1,sum=0;i<=100;i++));do
[ $[i%2] -eq 1 ] && let sum+=i
done
echo sum=$sum
1.4、for循环中循环体可并行执行,使脚本运行更快
用法:给for循环的循环体加上大括号,然后在大括号后面加上&符号即可
for name in列表;do
{
循环体
}&
done
wait
1.5、for循环并行检测局域网中存活的主机
搜寻自己指定ip(子网掩码为24的)的网段中,UP的ip地址
#!/bin/bash
#说明:此脚本是用来检测局域网中指定的网段有哪些主机开启
#用法:直接执行此脚本,然后输入你想探测的网段地址即可,例如:192.168.10.0网段有哪些主机开启
read -p "请输入你想查看主机为开启状态的网段地址[例如:192.168.1.0]:" net
echo $net | egrep -o "\"
[ $? -eq 0 ] || (echo "你的输入有误,请重新输入!!!";exit 10)
IP=$(echo $net|egrep -o "^([0-9]{1,3}\.){3}")
for i in {1..254};do
{
# echo $IP$i
ping -c 1 -w 1 $IP$i &> /dev/null && echo "$IP$i主机开启"
}&
done
分析:请输入一个IP地址例192.168.37.234,如果格式不是0.0.0.0则报错退出;正确则进入循环,IP变量的值为192.168.37. i的范围为1-254,并行ping 192.168.37.1-154,ping通就输出此IP为UP。直到循环结束。
经过测试:上面这个脚本如果循环体大括号后面不加&符号,运行完需要200多秒,加上&之后,运行2秒即可完成。
2、while循环结构语法及实例
2.1、while循环结构语法
while循环控制条件
do
指令
done
循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环
2.2、特殊用法(遍历文件的每一行)
while read line; do
循环体
done < /PATH/FROM/SOMEFILE
或
cat /PATH/FROM/SOMEFILE | while read line; do
循环体
done
依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line
2.3、100以内所有正奇数之和
#!/bin/bash
sum=0
i=1
while [ $i -le 100 ];do
if [ $[$i%2] -ne 0 ];then
let sum+=i
let i++
else
let i++
fi
done
echo "100以内所有奇数之和为:$sum"
分析:sum初始值为0,i的初始值为1;请输入一个数,先判断输入的是否含有除数字以外的字符,有,就报错;没有当i<100时,进入循环,判断 i÷2取余是否不为0,不为0时奇数,sum=sum+i,i+1,为0,i+1;循环结束,最后输出sum的值。
2.4、每隔2秒记录一次系统负载情况
#!/bin/bash
while true
do
uptime
sleep 2
done
提示:while true表示条件永远为真,会一直运行,这种我们称为守护进程。
2.5、把执行内容追加到log里,使用微秒为单位
#!/bin/bash
while [ 1 ]
do
uptime >>./uptime.log
usleep 1000000#这里是微秒单位,1秒等于1000000微秒
done
2.6、使用while循环计算从1加到1000000
#!/bin/bash
i=1
sum=0
while((i<=1000000))
do
((sum=sum+i))
((i++))
done
echo "sum=$sum"
以上脚本执行的时间
[root@localhost ~]# time bash 1.sh
sum=500000500000
real 0m15.501s
user 0m14.611s
sys 0m0.737s
2.7、使用计算公式计算从1加到1000000
#!/bin/bash
#快速求和计算公式((sum=n*(n+1)/2))
n=1000000
((sum=$n*($n+1)/2))
echo "sum=$sum"
以上脚本执行的时间
sum=500000500000
real 0m0.024s
user 0m0.006s
sys 0m0.015s
可以看到使用算法公式的效率要比没有使用算法公式的while快很多倍。
2.8、while读入文件内容的3种方式
方法1:
exec < FILE
sum=0
while read line
do
cmd
done
方法2:
cat ${FILE_PATH}| while read line
do
cmd
done
方法3:
while read line
do
cmd
done
3、until循环结构语法及实例
3.1、until循环结构语法
until循环条件
do
指令
done
until是条件不满足就一直执行下面的指令,条件满足就会退出
提示:until应用场合不多,了解就行
3.2、监控user1用户,发现登录就杀死
#!/bin/bash
until pgrep -u user1 &> /dev/null;do
sleep 1
done
pkill -9 -u user1
分析:每隔1秒扫描,直到发现user1用户登录,杀死这个进程,退出脚本,用于监控用户登录
3.3、until从1加到100范例
#!/bin/bash
i=1
until ((i>100))
do
((sum=sum+i))
((i++))
done
echo $sum
可以看出until是不满足条件就执行循环,满足条件就退出
4、select循环结构语法及实例
4.1、select循环结构语法
select variable in list
do
循环体命令
done
1、select循环主要用于创建菜单,按数字顺序排列的菜单项将显示在标准错误上,并显示PS3提示符,等待用户输入
2、用户输入菜单列表中的某个数字,执行相应的命令
3、用户输入被保存在内置变量 REPLY中
4、select是个无限循环,因此要记住用 break命令退出循环,或用 exit按命令终止脚本。也可以按 ctrl+c退出循环
5、select和经常和 case联合使用
6、与for循环类似,可以省略 in list,此时使用位置参量
4.2、select循环结构实例
#!/bin/bash
PS3="请输入你需要选择的菜单序号:"
select menu in米饭包子饺子面条quit;do
case $REPLY in
1|2)
echo "你选择的是米饭或包子,价格为3元每份。"
;;
3|4)
echo "你选择的是饺子或面条,价格为10元每份。"
;;
5)
break
;;
*)
echo "没有这个选项,请重新选择!!!"
esac
done
运行结果:
[root@localhost script]# bash select.sh
1)米饭
2)包子
3)饺子
4)面条
5) quit
请输入你需要选择的菜单序号:2
你选择的是米饭或包子,价格为3元每份。
请输入你需要选择的菜单序号:3
你选择的是饺子或面条,价格为10元每份。
请输入你需要选择的菜单序号:6
没有这个选项,请重新选择!!!
请输入你需要选择的菜单序号:5
[root@localhost script]#
到此,shell中的四大循环结构就介绍完毕了。