随堂练习 shell脚本(四)

流程控制

  条件选择

    条件判断

      单分支条件

选择执行 if 语句

格式

if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi

单分支

if  判断条件;then

  条件为真的分支代码
fi

双分支

if  判断条件; then

  条件为真的分支代码
else
  条件为假的分支代码
fi

多分支

if  判断条件1; then

  条件1为真的分支代码

elif  判断条件2; then

  条件2为真的分支代码

elif  判断条件3; then

  条件3为真的分支代码
...
else
  以上条件都为假的分支代码
fi

说明:

多个条件时,逐个条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if语句

if 语句可嵌套

范例

#根据命令的退出状态来执行命令

if ping -c1 -W2 station1 &> /dev/null ; then

  echo 'station1 is UP'

elif grep -q 'station1' ~/maintenance.txt; then

  echo 'station1 is undergoing maintenance'

else

  echo 'station1 is unexpectedly DOWN!'

  exit 1

fi

范例:身体质量指数 (BMI)

[root@centos8 ~]# cat if_bmi.sh

#!/bin/bash

read -p "请输入身高(m为单位):" HIGH

if [[ ! "$HIGH" =~ ^[0-2](.[0-9]{,2})?$ ]]; then

  echo "输入错误的身高"

  exit 1

fi

read -p "请输入体重(kg为单位):" WEIGHT

if [[ ! "$WEIGHT" =~ ^[0-9]{1,3}$ ]]; then echo "输入错误的体重"; exit 1

fi

BMI=`echo $WEIGHT/$HIGH^2|bc`

if [ $BMI -le 18 ]; then

  echo "太瘦了,多吃点"

elif [ $BMI -lt 24 ]; then

  echo "身材很棒"

else

  echo "太胖了,注意节食,加强运动"

fi

条件判断 case 语句

格式

case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac

case 变量引用 in

PAT1)

  分支1

  ;;

PAT2)

  分支2

  ;;

...

*)

  默认分支

  ;;

esac

case支持glob风格的通配符:

*   任意长度任意字符

?   任意单个字符

[]   指定范围内的任意单个字符

|   或者,如: a|b

范例

[root@centos8 scripts]# cat case_yesorno.sh

#!/bin/bash

read -p "Do you agree(yes/no)?" INPUT

INPUT=`echo $INPUT | tr 'A-Z' 'a-z'`

case $INPUT in

y|yes)

  echo "You input is YES"

  ;;

n|no)

  echo "You input is NO"

  ;;

*)

  echo "Input false,please input yes or no !"

esac

[root@centos8 scripts]# cat case_yesorno2.sh

#!/bin/bash

read -p "Do you agree(yes/no)?" INPUT

case $INPUT in

[yY]|[Yy][Ee][Ss])

  echo "You input is YES"

  ;;

[Nn]|[Nn][Oo])

  echo "You input is NO"

  ;;

*)

  echo "Input false,please input yes or no !"

esac

范例:运维菜单实现版本2

[root@centos8 scripts]# cat work_menu.sh

#!/bin/bash

echo -en "E[$[RANDOM%7+31];1m"

cat <<EOF

请选择:

1)备份数据库

2)清理日志

3)软件升级

4)软件回滚

5)删库跑路

EOF

echo -en "E[0m"

read -p "请输入上面数字1-5:" MENU

case $MENU in

1)

  ./backup.sh

  ;;

2)

  echo "清理日志"

  ;;

3)

  echo "软件升级"

  ;;

4)

  echo "软件回滚"

  ;;

5)

  echo "删库跑路"

  ;;

*)

  echo "INPUT FALSE !"

esac

练习
1、编写脚本 createuser.sh,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之。并设置初始密码为123456,显示添加的用户的id号等信息,在此新用户第一次登时,会提示用户立即改密码,如果没有参数,就提示:请输入用户名

2、编写脚本 yesorno.sh,提示用户输入yes或no,并判断用户输入的是yes还是no,或是其它信息

3、编写脚本 filetype.sh,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)

4、编写脚本 checkint.sh,判断用户输入的参数是否为正整数

5、编写脚本 reset.sh,实现系统安装后的初始化环境,包括:1、别名 2、环境变量,如PS1等 3、安装常用软件包,如:tree 5、实现固定的IP的设置,6、vim的设置等

循环

将某代码段重复运行多次,通常有进入循环的条件和退出循环的条件

重复运行次数

  循环次数事先已知

  循环次数事先未知

常见的循环的命令:for, while, until

格式1:

for NAME [in WORDS ... ] ; do COMMANDS; done

for 变量名 [ in 列表 ];do

  循环体

done

for 变量名 [ in 列表 ]

do
  循环体

done

执行机制

依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束

for循环列表生成方式:

  直接给出列表

  整数列表:

{start..end}

$(seq [start [step]] end)

返回列表的命令:

$(COMMAND)

使用glob,如:*.sh

变量引用,如:$@,$*,$#

范例:面试题,计算1+2+3+...+100的结果

[root@centos8 ~]# sum=0;for i in {1..100};do let sum+=i;done ;echo sum=$sum

sum=5050

[root@centos8 ~]# seq -s+ 100 | bc5050

5050

范例

[root@centos8 ~]# cat /data/scripts/for_sum.sh

#!/bin/bash

sum=0

for i in $* ; do

  let sum+=i

done

echo sum=$sum

[root@centos8 ~]# bash /data/scripts/for_sum.sh 1 2 3 4 5 6

sum=21

范例: 九九乘法表

#!/bin/bash

for i in {1..9};do

  for j in `seq $i` ;do

  echo -e "${j}x${i}=$[i*j] c"

  done

  echo

done

生产案例:将指定目录下的所有文件的后缀改名为 bak 后缀

[root@centos8 ~]# cat /data/scripts/for_rename.sh

#!/bin/bash

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 for_dir.sh

#!/bin/bash

for i in {1..365};do

  DIR=`date -d "-$i day" +%F`

  mkdir /data/test/$DIR -pv

  cd /data/test/$DIR

  for n in {1..10};do

    touch $RANDOM.log

  done

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

rm -rf $DIR/*-*-*

面试题:扫描一个网段:10.0.0.0/24,判断此网段中主机在线状态,将在线的主机的IP打印出来

[root@centos8 ~]# cat /data/scripts/for_scan_host.sh

#!/bin/bash

NET=10.0.0

for ID in {1..254};do

  {

  ping -c1 -W1 $NET.$ID &> /dev/null && echo $NET.$ID is up || echo $NET.$ID is down

  }&

done

wait

格式 2

双小括号方法,即((…))格式,也可以用于算术运算,双小括号方法也可以使bash Shell实现C语言风格的变量操作

I=10;((I++))

for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done

for ((控制变量初始化;条件判断表达式;控制变量的修正表达式))

do

循环体

done

说明

控制变量初始化:仅在运行到循环代码段时执行一次

控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断

范例:

#!/bin/bash

for((sum=0,i=1;i<=100;sum+=i,i++));do

  true

done

echo $sum

范例:九九乘法表

#!/bin/bash

#语法 1 实现

for i in {1..9};do

  for j in `seq $i`; do

    echo -e "${j}x${i}=$((j*i)) c"

  done

  echo

done

#语法 2 实现

for((i=1;i<10;i++)); do

  for((j=1;j<=i;j++)); do

    echo -e "${j}x$i=$((j*i)) c"

  done

  echo

done

范例:等腰三角形

[root@centos8 scripts]# cat for_triangle.sh

#!/bin/bash

read -p "请输入三角形的行数:" line

for((i=1;i<=line;i++));do

  for((k=0;k<=line-i;k++));do

    echo -e ' c'

  done

  for((j=1;j<=2*i-1;j++));do

    echo -e '*c'

  done

  echo

done

范例:生成进度

[root@centos8 ~]# for ((i=0;i<=100;++i)); do printf "e[4D%3d%%" $i; sleep 0.1s; 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天早上想再吃时,只剩下一个桃子了。求第一天共摘了多少?

原文地址:https://www.cnblogs.com/xuanlv-0413/p/13258564.html