一、for循环语句
- for语句是读取不同的变量值,用来逐个执行同一组命令
语法结构如下:
for 变量名 in 取值列表
do
命令序列
done
例1:为系统批量添加用户
#/bin/bash
#
list=`cat /root/1.txt` ## 将要添加的用户名存放在1.txt文件中(一行一个用户名)
for i in $list ## 每次循环从列表里读取一个用户名
do
useradd $i ## 添加账户
echo "123456" | passwd --stdin $i > /dev/null ##为账户设置密码,为了不让信息在屏幕输出所以将信息导入黑洞中
echo "用户${i}添加成功!" ## 在屏幕上输出用户添加成功的信息
done
例2:根据IP地址范围检查主机在线状态
#!/bin/bash
#
for i in `seq 131 134`;do ## 从数字131-134中每次读取一个数
ping -c 3 -i 0.2 -w 3 "192.168.50.$i" > /dev/null ## 使用ping命令测试192.168.50段的地址,将输出信息导入黑洞
if [ $? -eq 0 ];then ## 使用if语句进行条件判断,如果上一个命令执行后返回结果为0,那么执行以下语句
echo "192.168.50.$i is up!" ## 在屏幕上输出信息
else ## 如果返回值为非0值,执行以下语句
echo "192.168.50.$i is down!" ## 在屏幕上输出信息
fi
done
备注:ping命令中的c、i、w选项含义分别是发送数据包的数量、测试间隔时间(s)和等待超时时间
例3:输出1-100中能被2整除的所有数,并求其和
#!/bin/bash
#
sum=0 ## 定义和sum为0(因为刚开始还没有开始累加,最初值当然为0)
for i in `seq 1 100`;do ## 从数字1-100中每次读取一个数
if [ `expr $i % 2` -eq 0 ];then ## 用if进行条件判断,如果用这个数去对2进行取余,如果结果为0,执行以下语句
echo $i ## 将这个数在屏幕上进行输出
let sum=$sum+$i ## 将符合条件的数进行累加求和(不明白的话可以代一个数进去算一下)
fi
done
echo $sum ## 输出和
二、while循环语句
- while语句:重复测试某个条件,只要条件成立则反复执行
语法结构如下:
while 条件测试操作
do
命令序列
done
例1:输出1-100所有奇数
#!/bin/bash
#
i=1 ## 定义i初始值从1开始
while [ $i -le 100 ];do ## 只要i的值小于等于100就会执行以下语句
if [ `expr $i % 2` -eq 1 ];then ## 判断如果这个值对2取余后为1,那么执行以下语句
echo $i ## 输出该值
fi
let i++ ## 让i自身加1后再次循环直到不满足条件
done
例2:小游戏:猜商品价格
设计思路:利用系统中的RANDOM变量对其取余使之生成一定范围内的随机数,用read -p命令与用户交互输入数字后脚本通过if语句进行条件判断,如果输入的数与系统生成随机数相同则输出相应提示内容并退出整个循环语句,如果猜高了或低了则使用if分支语句继续进行条件判断并输出对应内容,每进行一次循环就使变量i(游戏次数加1),直到用户猜对后输出共进行了多少轮游戏。
#!/bin/bash
# 小游戏:猜商品价格
clear
i=1
price=$(expr $RANDOM % 1000)
while true;do
read -p "请输入商品价格:" a
if [ $a -eq $price ];then
echo "恭喜您猜对了!"
break
elif [ $a -gt $price ];then
echo "您猜高了!"
elif [ $a -lt $price ];then
echo "您猜低了!"
fi
let i++
done
echo "您猜了${i}次"
三、until循环语句
- until语句:重复测试某个条件,只要条件不成立则反复执行
语法结构如下:
until 条件测试操作
do
命令序列
done
例1:计算1-50的和
#!/bin/bash
#
i=1 ## 定义i起始值为1
sum=0 ## 定义和sum起始值为0
until [ $i -eq 51 ];do ## 只要i不等于51则执行下面语句
let sum+=$i ## 求和(等同于:let sum=$sum+$i)
let i++ ## 让i值自身加1后继续循环
done
echo "和为:$sum" ## 输出sum和的值
有人可能会问,为什么不是等于50还是要等于51?如果是50代入计算一下,i的值刚好为50时满足条件,until语句就退出循环了,并不会继续执行下面的let sum+=$i,所以最后求得的和中就少了50
例2:为指定用户发送在线消息
①若用户不在线(未登录系统),则每5秒尝试一次,直至用户登陆系统后再发送信息
②用户名与消息通过位置参数传递给脚本
编写思路:1、首先,用户名与消息都是以位置变量方式传给脚本执行,所以当位置变量小于一个(例如不填)的时候会提示报错信息告知用户输入错误,这个时候就要使用条件判断语句if;
2、用户的类别也是有区别的,肯定不能输入不存在的用户或不能登录的用户,所以这个时候又要用到if语句和grep命令对系统中的passwd文件进行筛选和判断,确认是否为系统中可登录的用户,如果不是则输出相应信息;
3、这一步就是判断用户是否在线了,我们可以用who命令查看当前在线的所有用户,但需求中还要求用户若不在线则5秒重试,这时候可以想到之前的until语句(只要条件不成立则反复执行),让其进入死循环(为true)时就可以不断重复执行;
4、最后就是给发送消息了,发送消息可以使用write命令即可实现,最后发送完毕在屏幕上提示发送成功信息。
有了思路(框架)下面就是给框架里加料了:
#!/bin/bash
# 给在线用户发送消息
username=$1
if [ $# -lt 1 ];then
echo "请输入正确的用户名!"
exit 0 ## 直接退出程序,不再执行下面的任何语句
fi
if grep "^$username" /etc/passwd > /dev/null;then :
else
echo "用户不存在!"
exit 1
fi
until who | grep "$username" > /dev/null;do
echo "该用户不在线!"
sleep 5 ## 休眠5秒
done
echo "$2" | write "$username"
echo "${username}发送成功!"