Shell 基本语法结构(4):循环结构

删除回忆录丶 提交于 2019-12-26 01:22:22

1. 循环语法基础结构

1.1. for 结构

1.1.1. 列表循环

列表 for 循环:用于将一组命令执行已知的次数

for variable in {list}
	do
		command1
		command2
		...
	done

或者

for variable in a b c
	do 
		command1
		command2
		...
	done
1.1.2. 不带列表循环
for variable 
	do
		command1
		command2
		...
	done
1.1.3. 类 C 风格的 for 循环
  • 基本语法结构
for (( expr1;expr2;expr3 )) 
	do
		command1
		command2
		...
	done
1.1.4. 学习示例

打印1至50

#!/bin/bash
for i in {0..50..2}
do
    echo ${i}
done
# 类 c 风格
for (( i=1; i<=50; i++))
do
   echo ${i}
done

1.2. while 结构

条件为真进入循环,条件为假则退出循环

while 表达式
	do
		command1
	done

示例:用 while结构循环打印1-5

i=1
while [[ ${i} -le 5 ]];
do
	echo ${i}
	let i++
done	

1.3. until 结构

条件为假就进入循环,条件为真退出循环

until 表达式 # 退出循环条件
do
	command1
	command2
	...
done

学习示例

#!/bin/bash
n=10
until [ $n -lt 1 ]
do
    n=$[ $n - 1 ]
done
echo "n: "$n

# chen @ localhost in ~/Shell [17:25:38] C:1
$ chmod +x test_for2.sh 

# chen @ localhost in ~/Shell [17:25:55] 
$ ./test_for2.sh 
n: 0

2. 嵌套循环语法结构

  • 一个循环体内包含另一个完整的循环结构
  • 每次循环都会触发内部循环,直至内部循环完成,才接着执行下一次的外部循环
  • for 循环、while循环和 util循环可以相互嵌套

3. 练习案例

3.1. 计算 1-100 奇数的和
#!/usr/bin/env bash

#
sum=0
for i in {1..100..2} ;
do
    let sum=${sum}+${i}
done
echo "1-100奇数和: "${sum}

# 方法2
for (( i=1; i<=50; i++ ))
do
    test $[${i}%2] -ne 0 && let sum=${sum}+${i}
done
echo "1-100奇数和: "${sum}

3.2. 判断质数

判断用户输入的数是否为质数

#!/usr/bin/env bash

read -p "请输入一个正整数: " number


expr ${number} + 0 &> /dev/null
[[ $? -eq 0 ]] ||  echo "输入数不是整数"; exit
[[ ${number} -eq 1 ]] && echo "${number} 不是质数" && exit
[[ ${number} -eq 2 ]] && echo "${number} 是质数" && exit

for i in $( seq 2 $[ $[ ${number}-1 ]/2 ]) ; do
    [[ $[ ${number}%${i} ]  -eq 0 ]] &&  echo "${number} 不是质数" && exit
done

echo "${number} 是质数"
3.3. 局域网内检查主机网络通信

局域网内,把能 ping 通的 ip 和不能 ping 通的 IP 分类,并保存到两个文件中

#!/usr/bin/env bash

ip=192.168.10
for (( i = 1; i <= 254; ++i ))
do
{   ping -c1 ${ip}.${i} &> /dev/null
    if [[ $? -eq 0 ]];then
        echo "---${ip}.${i} is ok---" | tee -a /tmp/ip_up.txt
    else
        echo "---${ip}.${i} is down---" | tee -a /tmp/ip_down.txt
    fi

#    [[ $? -eq 0 ]] && echo "${ip}.${i} is ok" >> /tmp/ip_up.txt || echo "${ip}.${ip} is down" >> /tmp/ip_down.txt
}&
done
wait
echo "-----------------------检测完毕---------------------"

注: 这个示例中使用并行执行:
{程序}& 表示将程序放到后台并执行,如果需要等待程序执行完毕在进行下面内容,需要加 wait

3.4. 脚本同步系统时间
3.4.1 具体需求
  • 每隔30秒同步一次系统时间,时间同步服务器 192.168.10.96
  • 如果同步失败,则进行邮件报警,每次失败都报警
  • 同步成功,也进行邮件报警,但是成功100次才通知一次
3.4.2 脚本实现
#!/usr/bin/env bash

# Auth: chen
# Email: chen3494269@163.com
# Desc: 同步系统时间
# Func: 每隔 30 秒同步一次系统时间,时间同步服务器 192.168.10.96
#       如果同步失败,则进行邮件报警,每次失败都报警
#       同步成功,也进行邮件报警,但是成功100次才通知一次
# Date: 2019/10/10
# Version: v1.0

NTP_SERVER=192.168.10.96
count=0
SUCCESS_NUM=100
while true;
do
    ntpdate ${NTP_SERVER} &> /dev/null
    if [[ $? -ne 0 ]]; then
        echo "system data failed" | mail -s "check system date" root@localhost
    else
        let count++
        if [[ ${count} -eq ${SUCCESS_NUM} ]]; then
            echo "system data failed" | mail -s "check system date" && count=0          
        fi
    fi
sleep 30
done
3.5. 打印指定图案
3.5.1 图案

1
1 2
1 2 3
1 2 3 4
1 2 3 4 5

3.5.2 脚本实现
#!/usr/bin/env bash

for i in {1..5}
do
    for (( j = 1; j <= ${i}; ++j ))
    do
        echo -n ${j}
    done
    # 换行
    echo

done
3.5.3 图案

5
5 4
5 4 3
5 4 3 2
5 4 3 2 1

3.5.4 脚本实现
for i in {1..5}
do
    for (( j = 5; j >= 6-${i} ; --j ))
    do
        echo -n ${j}
    done
    # 换行
    echo

done
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!