随堂练习 shell脚本(五)

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 \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 "请点菜(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"

posted @ 2020-07-07 11:19  空白的旋律  阅读(198)  评论(0编辑  收藏  举报