while 循环
格式:
while COMMANDS;do COMMANDS;done
while CONDITION; do
循环体
done
说明:
CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环,因此:CONDTION 一般应该有循环控制变量;而此变量的值会在循环体不断地被修正
进入条件:CONDITION 为 true
退出条件:CONDITION 为 false
无限循环
while true;do
循环体
done
范例:
#配置发邮件的邮箱
[root@centos8 ~]# cat .mailrc
set from=llxuan0360@163.com
set smtp=smtp.163.com
set smtp-auth-user=llxuan0360@163.com
set smtp-auth-password=WSNGSJXNSFGRGFEDFGREF
set smtp-auth=login
set ssl-verify=ignore
[root@centos8 ~]# cat while_diskcheck.sh
#!/bin/bash
WARNING=80
while : ;do
USE=`df | sed -nr '/^/dev/se/s#.*([0-9]+)%.*#1#p' | sort -nr | head -n1`
if [ $USE -gt $WARNING ]; then
echo Disk will be full from `hostname -I` | mail -s "disk warning" llxuan0360@163.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值
until 循环
格式
until COMMANDS;do COMMANDS;done
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
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
...省略
循环控制语句 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
for ((i=0;i<10;i++));do
for((j=0;j<10;j++));do
[ $j -eq 5 ] && break
done
echo --------------------------------------------
done
范例
[root@centos8 script40]# cat break_for.sh
#!/bin/bash
for ((i=0;i<10;i++));do
for((j=0;j<10;j++));do
[ $j -eq 5 ] && break 2
done
echo -----------------------------------------------
done
[root@centos8 script40]# bash break_for.sh
0
1
2
3
4
范例
[root@centos8 script40]# cat menu.sh
#!/bin/bash
sum=0
COLOR='echo -e 33[1;31m'
COLOR2='echo -e 33[1;32m'
END=" 33[0m"
while true;do
echo -e " 33[33;1mc"
cat <<-EOF
1) 鲍鱼
2) 满汉全席
3) 龙虾
4) 燕窝
5) 帝王蟹
6) 退出
EOF
echo -e " 33[0m"
read -p "请点菜(1-6):" MENU
case $MENU in
1|4)
$COLOR'菜价:$10'$END
let sum+=10
;;
3|5)
$COLOR'菜价:$20'$END
;;
2)
$COLOR'菜价:$100'$END
let sum+=1000
;;
6)
$COLOR2"你点的菜总价格是:$$sum"$END
break
;;
*)
echo "点错了,没有这道菜"
;;
esac
$COLOR2"你点菜总价格是:$$sum"$END
done
范例
[root@centos8 script40]# cat guess.sh
#!/bin/bash
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
while [ $You can't use ' macro parameter character -gt 0 ]
do
echo $*
shift
done
./doit.sh a b c d e f g h
范例:shift.sh
#!/bin/bash
until [ -z "$1" ]
do
echo "$1"
shift
done
echo
./shfit.sh a b c d e f g h
范例
[root@centos8 ~]# vim shift_batch_user.sh
#!/bin/bash
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 longwang | read X ; echo $X
[root@centos8 ~]# echo longwang | while read X ; do echo $X;done
longwang
[root@centos8 ~]# echo longwang | { read X ; echo $X; }
longwang
[root@centos8 ~]# echo longwang | ( read X ; echo $X )
longwang
[root@centos8 ~]# echo longge wang zhang | ( read X Y Z; echo $X $Y $Z )
longge wang zhang
[root@centos8 ~]# echo longge wang zhang | while read X Y Z; do echo $X $Y $Z;done
longge wang zhang
范例
cat while_read_diskcheck.sh
#!/bin/bash
WARNING=80
MAIL=llxuan0360@163.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
lastb | sed -nr '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
范例:查看/sbin/nologin的shell类型的用户名和UID
cat while_read_passwd.sh
#!/bin/bash
while read line ;do
if [[ "$line" =~ /sbin/nologin$ ]] ;then
echo $line | cut -d: -f1,3
fi
done < /etc/passwd
范例:单词文件
[root@centos6 ~]# wc -l /usr/share/dict/linux.words
479829 /usr/share/dict/linux.words
select 循环与菜单
格式:
select NAME [ in WORDS ... ; ] do COMMANDS; done
select variable in list ;do
循环体命令
done
说明:
1)select 循环主要用于创建菜单,按数字顺序排列的菜单项显示在标准错误上,并显示 PS3 提示符,等待用户输入
2)用户输入菜单列表中的某个数字,执行相应的命令
3)用户输入被保存在内置变量 REPLY 中
4)select 是个无限循环,因此要用 break 命令退出循环,或用 exit 命令终止脚本。也可以按 ctrl+c 退出循环
5)select 经常和 case 联合使用
6)与 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"