循环
循环执行介绍
将某代码段重复运行多次,通常有进入循环的条件和退出循环的条件
重复运行次数
- 循环次数事先已知
- 循环次数事先未知
常见的循环的命令:for, while, until
for循环
格式1:
for 变量名 in 列表;do 循环体 done
执行机制: 依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束
for循环列表生成方式:
- 直接给出列表
- 整数列表:
{start..end} $(seq [start [step]] end)
- 返回列表的命令:
$(COMMAND)
- 使用glob,如:*.sh
- 变量引用,如:$@,$#
范例: 九九乘法表
#!/bin/bash
for i in {1..9};do
for j in seq $i
;do
echo -e "${j}x${i}=$[i*j]\t\c"
done
echo
done
范例:生产案例
[root@centos8 ~]#cat /data/script40/for_rename.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2020-01-03
#FileName: /data/script40/for_rename.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2020 All rights reserved
#********************************************************************
DIR=/data/test
cd $DIR
for FILE in * ;do
PRE=echo $FILE | sed -nr 's/(.*)\.([^.]+)$/\1/p'
# SUFFIX=echo $FILE | sed -nr 's/(.*)\.([^.]+)$/\2/p'
mv $FILE $PRE.bak
done
范例:M37期面试题,要求将目录YYYY-MM-DD/中所有文件,移动到YYYY-MM/DD/下
#1 yyyy-mm-dd10.sh 创建YYYY-MM-DD,当前日期一年前365天到目前共365个目录,里面有10个文件,$RANDOM.log [root@centos8 ~]#cat dir20.sh #!/bin/bash for i in {1..365};do DIR=date -d "-$i day" +%F
mkdir $DIR cd $DIR for n in {1..10};do touch $RANDOM.log done cd .. done #2 移动到YYYY-MM/DD/下 #!/bin/bash # DIR=/data/test cd $DIR for DIR in * ;do YYYY_MM=echo $DIR |cut -d"-" -f1,2
DD=echo $DIR |cut -d"-" -f3
[ -d $YYYY_MM/$DD ] || mkdir -p $YYYY_MM/$DD &> /dev/null mv $DIR/* $YYYY_MM/$DD done
格式2
双小括号方法,即((…))格式,也可以用于算术运算,双小括号方法也可以使bash Shell实现C语言风格的变量操作 I=10;((I++))
for ((控制变量初始化;条件判断表达式;控制变量的修正表达式)) do 循环体 done
说明:
- 控制变量初始化:仅在运行到循环代码段时执行一次
- 控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断
范例:
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2020-01-03
#FileName: for_sum2.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2020 All rights reserved
#********************************************************************
for((sum=0,i=1;i<=100;sum+=i,i++));do
true
done
echo $sum
范例:九九乘法表
#!/bin/bash # #******************************************************************** #Author: wangxiaochun #QQ: 29308620 #Date: 2020-01-03 #FileName: for_99_2.sh #URL: http://www.magedu.com #Description: The test script #Copyright (C): 2020 All rights reserved #******************************************************************** for ((i=1;i<10;i++));do for((j=1;j<=i;j++));do echo -e "${j}x${i}=$[i*j]\t\c" done echo done
练习:用 for 实现 1、判断/var/目录下所有文件的类型 2、添加10个用户user1-user10,密码为8位随机字符 3、/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件;分别读取每个文件,以K开头的输出为文件加stop,以S开头的输出为文件名加start,如K34filename stop S66filename start 4、编写脚本,提示输入正整数n的值,计算1+2+…+n的总和 5、计算100以内所有能被3整除的整数之和 6、编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态 7、打印九九乘法表 8、在/testdir目录下创建10个html文件,文件名格式为数字N(从1到10)加随机8个字母,如:1AbCdeFgH.html 9、打印等腰三角形 10、猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个。第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,只剩下一个桃子了。求第一天共摘了多少?
while循环
格式:
while CONDITION; do 循环体 done
说明:
CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环,因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正 进入条件:CONDITION为true 退出条件:CONDITION为false
范例:
#配置发邮件的邮箱 [root@centos8 ~]#cat .mailrc set from=29308620@qq.com set smtp=smtp.qq.com set smtp-auth-user=29308620@qq.com set smtp-auth-password=esvnhbnqocirbicf set smtp-auth=login set ssl-verify=ignore [root@centos8 ~]#cat while_diskcheck.sh #!/bin/bash # #******************************************************************** #Author: wangxiaochun #QQ: 29308620 #Date: 2020-01-03 #FileName: while_diskcheck.sh #URL: http://www.magedu.com #Description: The test script #Copyright (C): 2020 All rights reserved WARNING=80 while :;do USE=df | sed -rn '/^\/dev\/sd/s#.* ([0-9]+)%.*#\1#p' |sort -nr|head -n1
if [ $USE -gt $WARNING ];then echo Disk will be full fromhostname -I
| mail -s "disk warning" 29308620@qq.com fi sleep 10 done
练习:用while实现 1、编写脚本,求100以内所有正奇数之和 2、编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态,并统计在线和离线主机各多少 3、编写脚本,打印九九乘法表 4、编写脚本,利用变量RANDOM生成10个随机数字,输出这个10数字,并显示其中的最大值和最小值 5、编写脚本,实现打印国际象棋棋盘 6、后续六个字符串:efbaf275cd、4be9c40b8b、44b2395c46、f8c8873ce0、b902c16c8b、ad865d2f63是通过对随机数变量RANDOM随机执行命令: echo $RANDOM|md5sum|cut –c1-10 后的结果,请破解这些字符串对应的RANDOM值
无限循环
while true; do 循环体 done
until循环
格式:
until CONDITION; do 循环体 done
说明:
进入条件: CONDITION 为false 退出条件: CONDITION 为true
无限循环
until false; do 循环体 Done
循环控制语句 continue
continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层
格式:
while CONDITION1; do CMD1 ... if CONDITION2; then continue fi CMDn ... done
范例:
[root@centos8 script40]#cat continue_for.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2020-01-03
#FileName: continue_for.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2020 All rights reserved
#********************************************************************
for ((i=0;i<10;i++));do
for((j=0;j<10;j++));do
[ $j -eq 5 ] && continue 2
echo $j
done
echo ---------------------------
done
[root@centos8 script40]#bash continue_for.sh
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
0
1
2
3
4
循环控制语句 break
break [N]:提前结束第N层整个循环,最内层为第1层
格式:
while CONDITION1; do CMD1 ... if CONDITION2; then break fi CMDn ... done
范例:
[root@centos8 script40]#cat break_for.sh #!/bin/bash # #******************************************************************** #Author: wangxiaochun #QQ: 29308620 #Date: 2020-01-03 #FileName: continue_for.sh #URL: http://www.magedu.com #Description: The test script #Copyright (C): 2020 All rights reserved #******************************************************************** for ((i=0;i<10;i++));do for((j=0;j<10;j++));do [ $j -eq 5 ] && break 2 echo $j done echo --------------------------- done [root@centos8 script40]#bash break_for.sh 0 1 2 3 4
范例:
[root@centos8 script40]#cat menu.sh #!/bin/bash # #******************************************************************** #Author: wangxiaochun #QQ: 29308620 #Date: 2020-01-03 #FileName: menu.sh #URL: http://www.magedu.com #Description: The test script #Copyright (C): 2020 All rights reserved #******************************************************************** sum=0 COLOR='echo -e \033[1;31m' COLOR2='echo -e \033[1;32m' END="\033[0m" while true;do echo -e "\033[33;1m\c" cat <<EOF 1) 鲍鱼 2) 满汉全席 3) 龙虾 4) 燕窝 5) 帝王蟹 6) 退出 EOF echo -e "\033[0m" read -p "请点菜: " MENU case $MENU in 1|4) $COLOR'菜价: $10'$END let sum+=10 ;; 3|5) $COLOR'菜价: $20'$END let sum+=20 ;; 2) $COLOR'菜价: $1000'$END let sum+=1000 ;; 6) $COLOR2"你点的菜总价格是 $sum"$END break ;; *) echo "点错了,没有这道菜" ;; esac $COLOR2"你点的菜总价格是 $sum"$END done
范例:
[root@centos8 script40]#cat guess.sh #!/bin/bash # #******************************************************************** #Author: wangxiaochun #QQ: 29308620 #Date: 2020-01-03 #FileName: guess.sh #URL: http://www.magedu.com #Description: The test script #Copyright (C): 2020 All rights reserved #******************************************************************** NUM=$[RANDOM%10] while read -p "输入 0-9 之间的数字: " INPUT ;do if [ $INPUT -eq $NUM ];then echo "恭喜你猜对了!" break elif [ $INPUT -gt $NUM ];then echo "数字太大了,重新猜!" else echo "数字太小了,重新猜!" fi done
循环控制 shift 命令
shift [n] 用于将参量列表 list 左移指定次数,缺省为左移一次。 参量列表 list 一旦被移动,最左端的那个参数就从列表中删除。while 循环遍历位置参量列表时,常用到 shift
范例:doit.sh
#!/bin/bash # Name: doit.sh # Purpose: shift through command line arguments # Usage: doit.sh [args] while [ $You can't use 'macro parameter character #' in math mode# -gt 0 ] # or (( $# > 0 )) do echo $* shift done ./doit.sh a b c d e f g h
范例:示例:shift.sh
#!/bin/bash #step through all the positional parameters until [ -z "$1" ] do echo "$1" shift done echo ./shfit.sh a b c d e f g h
范例:
[root@centos8 script40]#vim shift_batch_user.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2020-01-03
#FileName: shift_batch_user.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2020 All rights reserved
#********************************************************************
if [ $# -eq 0 ];then
echo "Usage: basename $0
user1 user2 ..."
exit
fi
while [ "$1" ];do
if id $1 &> /dev/null;then
echo $1 is exist
else
useradd $1
echo "$1 is created"
fi
shift
done
echo "All user is created"
[root@centos8 script40]#bash shift_batch_user.sh
Usage: shift_batch_user.sh user1 user2 ...
[root@centos8 script40]#bash shift_batch_user.sh tom alice jack
tom is exist
alice is exist
jack is created
All user is created
练习 1、每隔3秒钟到系统上获取已经登录的用户的信息;如果发现用户hacker登录,则将登录时间和主机记录于日志/var/log/login.log中,并退出脚本 2、随机生成10以内的数字,实现猜字游戏,提示比较大或小,相等则退出 3、用文件名做为参数,统计所有参数文件的总行数 4、用二个以上的数字为参数,显示其中的最大值和最小值
while read 特殊用法
while 循环的特殊用法,遍历文件或文本的每一行
格式:
while read line; do 循环体 done < /PATH/FROM/SOMEFILE
说明:依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line
范例:
[root@centos8 ~]#echo magedu | read X ; echo $X [root@centos8 ~]#echo magedu | while read X ; do echo $X;done magedu [root@centos8 ~]#echo magedu | { read X ; echo $X; } magedu [root@centos8 ~]#echo magedu | ( read X ; echo $X ) magedu [root@centos8 ~]#echo mage wang zhang | ( read X Y Z; echo $X $Y $Z ) mage wang zhang [root@centos8 ~]#echo mage wang zhang | while read X Y Z; do echo $X $Y $Z;done mage wang zhang
范例:
cat while_read_diskcheck.sh
#!/bin/bash
WARNING=80
MAIL=root@wangxiaochun.com
df |sed -nr "/^\/dev\/sd/s#^([^ ]+) .* ([0-9]+)%.*#\1 \2#p"|while read DEVICE USE;do
if [ $USE -gt $WARNING ] ;then
echo "$DEVICE will be full,use:$USE" | mail -s "DISK WARNING" $MAIL
fi
done
范例:
cat while_read_check_dos.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2020-01-03
#FileName: while_read_check_dos.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2020 All rights reserved
#********************************************************************
lastb | sed -rn '/ssh:/s@.* ([0-9.]{1,3}{3}[0-9]{1,3}) .*@\1@p'|sort |uniq -c |while read count ip ;do
if [ $count -gt 3 ];then
iptables -A INPUT -s $ip -j REJECT
fi
done
范例:
cat while_read_passwd.sh
#!/bin/bash
#
#********************************************************************
#Author: wangxiaochun
#QQ: 29308620
#Date: 2020-01-03
#FileName: while_read_passwd.sh
#URL: http://www.magedu.com
#Description: The test script
#Copyright (C): 2020 All rights reserved
#********************************************************************
while read line ;do
if [[ "$line" =~ /sbin/nologin$ ]] ;then
echo $line | cut -d: -f1,3
fi
done < /etc/passwd
select 循环与菜单
格式:
select variable in list ;do 循环体命令 done
说明:
- select 循环主要用于创建菜单,按数字顺序排列的菜单项显示在标准错误上,并显示 PS3 提示符,等待用户输入
- 用户输入菜单列表中的某个数字,执行相应的命令
- 用户输入被保存在内置变量 REPLY 中
- select 是个无限循环,因此要记住用 break 命令退出循环,或用 exit 命令终止脚本。也可以按 ctrl+c 退出循环
- select 经常和 case 联合使用
- 与 for 循环类似,可以省略 in list,此时使用位置参量
范例:
cat select.sh
#!/bin/bash
#
sum=0
PS3="请点菜(1-6): "
select MENU in 北京烤鸭 佛跳墙 小龙虾 羊蝎子 火锅 点菜结束;do
case $REPLY in
1)
echo $MENU 价格是 100
let sum+=100
;;
2)
echo $MENU 价格是 88
let sum+=88
;;
3)
echo $MENU价格是 66
let sum+=66
;;
4)
echo $MENU 价格是 166
let sum+=166
;;
5)
echo $MENU 价格是 200
let sum+=200
;;
6)
echo "点菜结束,退出"
break
;;
*)
echo "点菜错误,重新选择"
;;
esac
done
echo "总价格是: $sum"
本文链接:https://www.yunweipai.com/34342.html
网友评论comments