shell脚本——循环(for+while+until)
Posted 郭怀远
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell脚本——循环(for+while+until)相关的知识,希望对你有一定的参考价值。
文章目录
for循环
列表循环
#!/bin/bash
for tmp in 1..10
do
echo $tmp
done
或者
for tmp in one 2 三
do
echo $tmp
done
不带列表循环
不带列表的for循环执行时由用户指定参数和参数的个数
#!/bin/bash
for var
do
echo $var
done
echo "脚本后面有$#个参数"
[root@lamp test]# ./for.sh 1 2 3
1
2
3
脚本后面有3个参数
C语言风格的for循环
for(( expr1;expr2;expr3 ))
do
command
command
…
done
for (( i = 0; i <= 5; i++ ))
do
echo $i
done
expr1:定义变量并赋初值
expr2:决定是否进行循环(条件)
expr3:决定循环变量如何改变,决定循环什么时候退出
举例子
for ((i=1;i<=5;i++));do echo $i;done
for循环练习
计算1到100的奇数之和,方法不止一种
#!/bin/bash
sum=0
for (( i = 1; i <= 100; i+=2 ))
do
sum=$((i+sum))
done
echo $sum
sum=0
for (( i = 1; i <= 100; i+=2 ))
do
[ $[$i%2] -eq 1 ] && let sum=sum+$i
done
echo $sum
循环控制
- continue:继续;表示循环体内下面的代码不执行,重新开始下一次循环
- break:打断;马上停止执行本次循环,执行循环体后面的代码
- exit:表示直接跳出程序
#!/bin/bash
for i in 1..5
do
test $i -eq 3 && break || touch /tmp/file$i
done
echo "ok"
示例1: 输入一个正整数,判断是否为质数(素数)
#!/bin/bash
read -p "请输入一个数字判断是否是素数:" number
for (( i=2; i <= number/2; i++ ))
do
if [ $((number%i)) -eq 0 ];then
echo $number"不是素数"
exit
fi
done
echo $number"是素数"
示例2: 批量加5个新用户,以u1到u5命名,并统一加一个新组,组名为class,统一改密码为123
#!/bin/bash
#判断class组是否存在
cat /etc/group | grep class | &>/dev/null
# 不存在就创建
if [ $? -eq 0 ];then
groupadd class &>/dev/null
fi
# 创建5个用户
for (( i = 1; i <= 5; i++ ))
do
useradd -G class u$i
echo 123 | passwd --stdin u$i &>/dev/null
done
示例3 :写一个脚本,局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里,这是一个局域网内机器检查通讯的一个思路
#!/bin/bash
#定义ip范围
ip=192.168.80.
#循环的去ping该主机的ip
for (( i = 1; i <= 10; i++ ))
do
ping -c1 $ip$i &>/dev/null
if [ $? -eq 0 ];then
echo $ip$i >> /tmp/ok.txt
else
echo $ip$i >> /tmp/no.txt
fi
done
echo "执行完毕!"
并行执行
由于前面的程序执行太慢就采用并发执行,提高程序运行速度
程序&
表示将程序放到后台并行执行,如果需要等待程序执行完毕再进行下面内容,需要加wait
#!/bin/bash
#定义ip范围
ip=192.168.80.
#循环的去ping该主机的ip
for (( i = 1; i <= 10; i++ ))
do
ping -c1 $ip$i &>/dev/null
if [ $? -eq 0 ];then
echo $ip$i >> /tmp/ok.txt
else
echo $ip$i >> /tmp/no.txt
fi
&
done
wait
echo "执行完毕!"
对比
# 串行执行
[root@lamp test]# time ./ping.sh
执行完毕!
real 1m30.106s
user 0m0.016s
sys 0m0.091s
# 并发执行
[root@lamp test]# time ./ping.sh
执行完毕!
real 0m10.015s
user 0m0.038s
sys 0m0.024s
示例4:输入一个年份,判断是否是润年(能被4整除但不能被100整除,或能被400整除的年份即为闰年。)
#!/bin/bash
read -p "请输入一个年份:" year
if [ $(($year % 4)) -eq 0 -a $(($year % 100)) -ne 0 ];then
echo "$year是闰年"
elif [ $(($year % 400)) -eq 0 ];then
echo "$year是闰年"
else
echo "$year不是闰年"
fi
while循环
特点:条件为真就进入循环;条件为假就退出循环
语法结构
while 表达式
do
...
done
while [ 1 -eq 1 ] 或者 (( 1 > 2))
do
...
done
# 打印1到10的数字
#!/bin/bash
i=1
while [ $i -le 5 ]
do
echo $i
let i++
done
案例
写一个30秒同步一次时间,向同步服务器10.1.1.250的脚本,如果同步失败,则进行邮件报警,每次失败都报警;同步成功,也进行邮件通知,但是成功100次才通知一次
- 先配置一台时间同步服务器(NTP)
yum -y install ntp
修改配置文件vim /etc/ntp.conf
,添加允许同步的网段 - 通过sleep控制每30s同步一次时间,再判断同步是否成功,成功计数器count就++
- 安装mailx。
yum -y instqall mailx
,用来发送邮件
#!/bin/bash
count=0
ntp=192.168.44.122
while true
do
ntpdate 192.168.44.122 &>/dev/null
if [ $? -eq 0 ];then
let count++
if [ $count -eq 100 ];then
echo "系统时间同步成功" | mail -s '时间同步' root@localhost
count=0
fi
else
echo "系统时间同步失败" | mail -s '时间同步' root@localhost
fi
#阻塞30秒
sleep 30
echo "ok"
echo $count
done
通过命令tail -f /var/spool/mail/root
查看本机邮件
until循环
语法结构
特点:条件为假就进入循环;条件为真就退出循环
until expression [ 1 -eq 1 ] (( 1 >= 1))
do
...
done
# 打印1到10
#!/bin/bash
i=1
until [ $i -gt 10 ]
do
echo $i
let i++
done
示例:使用until语句批量创建10个用户,要求stu1—stu5用户的UID分别为1011—1015;stu6~stu10用户的家目录分别在/rhome/stu6—/rhome/stu10
#!/bin/bash
i=1
j=6
id=1011
until [ $i -gt 6 ]
do
useradd -d /rhome/stu$j -u $id stu$i
let i++
let j++
let id++
done
以上是关于shell脚本——循环(for+while+until)的主要内容,如果未能解决你的问题,请参考以下文章