shell编程之循环语句与函数

346 阅读3分钟

1. 循环语句

1.1 for循环语句

1.1.1 认识for循环语句

读取不同的变量值,用来逐个执行同一组命令

image.png

1.1.2 遍历for循环

  • 格式
  1. for 变量名 in 取值范围; do 代码块; done
  2. for 变量名 in 取值范围; { 代码块 ; }

注意:do done 可以用{}代替,循环代码写在同一行需要用;隔开

取值列表默认的分隔符是空格、换行、制表符(tab)

  • for循环变量值数值范围表达方式

表示数值1-5

  1. 1 2 3 4 5 用空格隔开
  2. {1..5}
  3. seq 1 5
[root@localhost ~]# for i in 1 2 3 4 5; do echo $i; done
[root@localhost ~]# for i in {1..5}; do echo $i; done
[root@localhost ~]# for i in $(seq 1 5); do echo $i; done

image.png

取奇数和偶数

  1. {1..5..2} ##步长为2 偶数同理从2开始
  2. seq 1 2 10 ##中间的2表示步长为2
[root@localhost ~]# for i in {1..5..2}; do echo $i; done
[root@localhost ~]# for i in $(seq 1 2 5); do echo $i; done

image.png

1.1.3 迭代for循环

  • 格式

for ((变量=初始值; 变量的取值范围; 变量的迭代方式)); do echo $i; done

[root@localhost ~]# for ((i=2; i<=10; i++)); do echo $i; done

image.png

1.1.4 for循环取值范围输入命令的结果

  • 格式

1.

for i in $(可以输出结果的命令)

2.

image.png

[root@localhost ky22]# for i in $(echo $PATH); do echo $i; done
[root@localhost ky22]# for i in `echo $PATH`; do echo $i; done

image.png

1.1.5 for语句应用示例

  • 批量添加用户
    • 用户名存放在user文件中,每行一个
    • 判断用户是否存在
    • 初始密码均设为123456
    • 验证脚本
#!/bin/bash

for username in $(cat /ky22/user)  //获取命令结果,使用绝对路径
do
        id $username &> /dev/null  //判断是否有用户信息
        if [ $? = 0 ];then         //如果返回值是0,输出用户已存在
                echo "${username}用户已存在"
        else                      //否则会创建用户,添加密码,最后显示用户创建成功
                useradd $username
                echo 123456 | passwd --stdin $username &> /dev/null
                echo "${username}创建成功"
        fi
done

image.png

  • 根据IP地址检查主机状态
    • IP地址存放在 ipadds.txt文件中,每行一个
    • 使用 ping命令检测各主机的连通性
//以下脚本用到了多线程执行
#!/bin/bash
for IP in {1..254} //规定取值范围
do
{   // {...}& 代表是将每个循环操作的进程放到后台执行,且后台不区分前后顺序
        ping -c 3 -i 0.5 -w 2 172.16.100.$IP &> /dev/null  //ping 172.16.100段的IP地址
        if [ $? -eq 0 ];then  //返回值是0就是主机存活,输出 IP is online,重定向
                echo "172.16.100.$IP is online" >> /ky22/1.txt
        else
                echo "172.16.100.$IP is offline"
        fi
}&
done
wait   //wait命令用于等待上面所有后台程序都执行完毕后再执行后面的shell语句
cat /ky22/1.txt  //查看/ky22/1.txt里的内容

image.png

1.2 while循环语句

1.2.1 认识while循环语句

重复测试某个条件,只要条件成立则反复执行

image.png

  • 格式

while 条件测试操作; do 代码块; done

[root@localhost ~]# while [ $i -le 10 ]; do echo $i;let i++; done

image.png

1.2.3 while循环取值范围输入命令的结果

  • 格式

1.

whlie read line //line为变量名

do

echo $line

done < 文件名

2.

可以输出结果的命令 | whlie read line //使用管道符传给while循环

do

echo $line

done

[root@localhost ky22]# while read line
> do
> echo $line
> done < 1.txt
[root@localhost ky22]# cat 1.txt | while read line
> do
> echo $line
> done

image.png

1.2.4 while语句应用示例

  • 批量添加用户
    • 用户名称以stu开头,按数字顺序进行编号
    • 一共添加20个用户,即 stu1、stu2、.... stu20
    • 初始密码均设为123456
#!/bin/bash
i=1   //定义变量i为循环的条件变量
while [ $i -lt 20 ]  //取值范围
do
        useradd stu$i 
        echo 123456 | passwd --stdin stu$i &> /dev/null
        echo "stu$i 创建成功"
        let i++  
done

image.png

  • 猜商品价格游戏0~999
    • 通过变量RANDOM获得随机数
    • 提示用户猜测并记录次数,猜中后退出循环
#!/bin/bash
NUM=$ [RANDOM % 1000]  //获取0~999的随机数
i=1  //定义变量i为循环的条件变量
a=0 //定义变量a为记录猜测次数的变量
while [ $i -eq 1 ]
do
    read -p "请输入你猜测的价格(0~999) :"price  //获取用户输入的数值
    if [ $price -eq $NUM ];then  //使用随机数和用户输入的数值比较,并且每次比较记录猜测次数,如果数值不等则一直会在死循环中重复猜测
        echo "恭喜!你猜对了! ! "
        let a++
        let i++
    elif [ $price -gt $NUM ];then
        echo "你猜高了!请继续..."
        let a++
    elif [ $price -lt $NUM ];then
        echo "你猜低了!请继续..."
        let a++
    fi
done
echo "你一共猜了$a次。"   //输出猜测的总次数

image.png

1.3 循环语句

1.3.1 认识until循环语句

重复测试某个条件,只要条件不成立则反复执行,与while正好相反

image.png

  • 格式

until 条件测试操作; do 代码块; done

[root@localhost ~]# until [ $i -ge 10 ]; do echo $i;let i++; done

image.png

1.3.2 until语句应用示例

  • 计算1~50的和值
    • 通过循环累加的方式计算1~50的和值
#!/bin/bash
sum=0  
i=1    
until [ $i -gt 50 ]  //只要i的值大于50就会跳出循环
do
    sum=$[sum + i]
    let i++
done
    echo $sum

image.png

  • 为指定用户发送在线消息
    • 若用户不在线(未登录系统),则每10分钟试一次,直至用户登录系统后在发送信息
    • 用户名与消息通过位置参数传递给脚本
[rot@localhost ~]# vim until-user.sh  //  ./xxx.sh 用户 消息内容
#/bin/bash
usename=$1
if [ $# -lt 1 ];then  //判断脚本后面有没有跟参数如果没有参数则输出内容并退出脚本进程且状态码返回1
    echo "Usage:`basename $0` <usemame> [<message>]"
    exit 1
fi
if grep "^$username:" /etc/passwd > /dev/null;then //使用grep过滤/etc/passwd文件查看是否存在脚本后面
else    //指定的用户名如果不存在此用户则退出脚本进程且状态码返回2
    echo "$username is not a user on this system."
    exit 2
fi
until who|grep "$username" > /dev/null   //使用until循环每隔10分钟判断指定的用户是否已登录操作系统如果没登录则每隔10分钟检测判断
do
    echo "$username is not logged on."
    sleep 600
done
shift;msg=$*
[[ "X"$msg== "X" ]] && msg="Are you ready ? $username"   //如果$*为空则msg也为空那此时&&左边条件成立并会执行右边的赋值操作如果msg不为空则不会执行右边的赋值操作
echo "$msg" | write $username   //通过write命令给用户发送消息
[root@localhost ~]# chmod +x until-user.sh
[root@localhost ~]# ./until-user.sh   //发给 root自己,消息为空