本章内容

  • 条件判断
  • 循环
  • 信号捕捉
  • 函数
  • 数组
  • 高级字符串操作
  • 高级变量
  • Expect

  • 取硬盘利用率

df | sed -rn ‘/^\dev\/sd/s/.[ ]+([0-9]{1,3})%./\1/p’
df | sed -rn ‘s/^\/dev\/sd.[ ]+([0-9]{1,3})%./\1/p’

流程控制

image.png

  • 过程式编程语言:

顺序执行
选择执行
循环执行

条件选择if语句

  • 选择执行:
  • 注意:if语句可嵌套
  • 单分支

if 判断条件;then
条件为真的分支代码
fi

  • 双分支

if 判断条件;then
条件为真的分支代码
else
条件为假的分支代码
fi

if语句

  • 多分支

if 判断条件1;then
条件为真的分支代码
elif 判断条件2;then
条件为真的分支代码
elif 判断条件3;then
条件为真的分支代码
else
以上条件为假的分支代码
fi

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

    简单示例:

    1. #!/bin/bash
    2. #
    3. #********************************************************************
    4. #Author: chaitc
    5. #Date: 2020-04-26
    6. #FileName: test_if.sh
    7. #Description: The test script
    8. #Copyright (C): 2020 All rights reserved
    9. #********************************************************************
    10. read -p "Please input you age:" AGE
    11. [[ "$AGE" =~ ^[0-9]+$ ]] || { echo Age is not digit; exit; }
    12. if [ "$AGE" -lt 18 ];then
    13. echo "good good study,day day up"
    14. elif [ "$AGE" -ge 18 -a "$AGE" -lt 60 ];then
    15. echo "good good work"
    16. elif [ "$AGE" -ge 60 -a "$AGE" -lt 150 ];then
    17. echo "good luck"
    18. else
    19. echo "You don't come from the earth"
    20. fi

    if示例

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

if ping -c1 -W2 station1 &> /dev/null;then
echo ‘Station1 is UP’
elif grep “station1” ~/maintenance.txt &> /dev/null
then
echo ‘Station1 is undergoing mantenance ‘
else
echo ‘Station1 is unexpectedly DOWN!’
exit 1
fi

  1. if ping -c1 -W2 192.168.195.128 &> /dev/null;then
  2. echo '192.168.195.128 is UP'
  3. elif grep "192.168.195.128" ~/maintenance.txt &> /dev/null
  4. then
  5. echo '192.168.195.128 is undergoing mantenance '
  6. else
  7. echo '192.168.195.128 is unexpectedly DOWN!'
  8. exit 1
  9. fi

条件判断:case语句

case 变量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;

*)
默认分支
;;
esac

case支持glob风格的通配符:
*:任意长度字符串
?:任意单个字符
[]:指定范围内的任意单个字符
a|b:a或b

练习

  • 1、编写脚本/root/bin/createuser.sh,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id号等信息

    1. if id $1 &> /dev/null;then
    2. echo "you put user $1 is exists"
    3. echo `id $1`
    4. else
    5. useradd $1
    6. echo "you have created success"
    7. echo `id $1`
    8. fi

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

    1. read -p "please input yes or no:" answer
    2. case $answer in
    3. [Yy]|[Yy][Ee][Ss])
    4. echo "you input is yes"
    5. ;;
    6. [Nn]|[Nn][Oo])
    7. echo "you input is no"
    8. ;;
    9. *)
    10. echo "sha dou bu shi"
    11. ;;
    12. esac
  • 3、编写脚本/root/bin/filetype.sh,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)

/boot/grub2/ 目录 /bin 软链接 /boot/grub2/grub.cfg 普通文件

  1. RED="\033[31m"
  2. YELLOW="\033[0;33m"
  3. RESET="\033[0m"
  4. #判断参数个数
  5. if [ $# -ne 1 ];then
  6. echo -e "${RED}you must be enter a parameter,only one!$RESET"
  7. exit 2
  8. fi
  9. case `ls -ld $1 | cut -c 1` in
  10. -)
  11. echo "general file"
  12. ;;
  13. d)
  14. echo "dir"
  15. ;;
  16. l)
  17. echo "link file"
  18. ;;
  19. *)
  20. echo "oher"
  21. ;;
  22. esac
  • 4、编写脚本/root/bin/checkint.sh,判断用户输入的参数是否为正整数

    1. #判断参数个数
    2. [ $# -eq 1 ] || { echo "please input one parameter";exit 2; }
    3. #判断用户输入的是否正整数
    4. if [[ $1 =~ ^[0-9]+$ ]];then
    5. echo "is int"
    6. else
    7. echo "not int"
    8. fi

    循环

  • 循环执行

将某代码重复运行多次
重复运行多少次
循环次数事先已知
循环次数事先未知
有进入条件和退出条件

  • for,while,until

    for循环

  • for 变量名 in 列表;do

循环体
done

  • 执行机制:

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

  • 列表生成方式:

(1)直接给出列表
(2)整数列表:
(a){start..ebd}
(b)$(seq [start [step]] end)
(3)返回列表的命令
$(COMMAND)
(4)使用glob,如:.sh
(5)变量引用:
$@,$

  • 多行重定向

脚本中EOF前加-
for i in {1..10};do
cat >> f1 <<-EOF
aaa
bbb
EOF
done

  • 创建10个用户,并设初始密码chaitc

    1. #方式1:
    2. #for I in $(seq 10);do
    3. # if ! id user$I &> /dev/null; then
    4. # useradd user$I &>/dev/null
    5. # echo "chaitc" | passwd --stdin user$I &> /dev/null
    6. # echo "user$I add successful."
    7. # else
    8. # echo "user$I is exist."
    9. # fi
    10. #done
    11. #方式2:
    12. for I in {1..10};do
    13. if id user$I &> /dev/null;then
    14. echo "user$I is exist."
    15. else
    16. useradd user$I &>/dev/null
    17. echo "chaitc" | passwd --stdin user$I &> /dev/null
    18. echo "user$I add successful."
    19. fi
    20. done

    批量删除临时用户:
    for i in {1..10};do userdel -r user$i;done

  • 扫描网络

    • 前台执行

      1. net=192.168.195
      2. for i in {1..254};do
      3. if ping -c1 -W1 $net.$i &> /dev/null;then
      4. echo $net.$i is up
      5. else
      6. echo $net.$i is down
      7. fi
      8. done
    • 后台执行

      1. net=192.168.195
      2. for i in {1..254};do
      3. { if ping -c1 -W1 $net.$i &> /dev/null;then
      4. echo $net.$i is up
      5. else
      6. echo $net.$i is down
      7. fi } &
      8. done
      9. wait

      加wait 会让后台执行退出

      1. net=192.168.195
      2. up=0
      3. down=0
      4. for i in {125..134};do
      5. ping -c1 -W1 $net.$i &> /dev/null && { echo $net.$i is up ;let ++up; } || { echo $net.$i is down; let ++down; }
      6. done
      7. wait
      8. echo up is $up
      9. echo down is $down
  • 打印矩阵

    1. high=$1
    2. width=$2
    3. for i in `seq $high`;do
    4. for j in `seq $width`;do
    5. color=$[RANDOM%7+31]
    6. echo -e "\033[1;5;${color}m*\033[0m\c"
    7. done
    8. echo
    9. done

    练习:用for实现

    image.png
    1、判断/var/目录下所有文件的类型

    1. cd /var
    2. for i in `ls /var` ;do
    3. case `ls -ld $i | cut -c 1` in
    4. -)
    5. echo "$i is general file"
    6. ;;
    7. d)
    8. echo "$i is dir"
    9. ;;
    10. l)
    11. echo "$i is link file"
    12. ;;
    13. *)
    14. echo "$i is oher"
    15. ;;
    16. esac
    17. done

7、打印九九乘法表
image.png

  • 取8个随机字母

openssl rand -base64 20 | tr -dc ‘[:alpha:]’ | head -c8

image.png

  • 打印象棋

image.png

while循环

image.png
image.png
image.png

  • 每10秒监测一次httpd服务,如果down掉,立马重启服务,并记录日志

image.png

until循环

image.png

  • 监测wang账号登录

image.png

循环控制语句continue

image.png

循环控制语句break

image.png

循环控制shift命令

image.png

  • 根据用户输入参数,批量创建用户

image.png

示例:doit.sh

image.png

示例:shift.sh

image.png

创建无限循环

image.png

练习

image.png

2、
image.png

特殊用法

image.png

  • 对文本文件逐行处理,打印/etc/passwd里uid是偶数的用户名和uid

image.png

  • 扫描硬盘空间利用率

image.png

特殊用法

image.png

image.png
image.png

select循环与菜单

image.png
image.png

select与case

image.png

信号捕捉trap

  • trap ‘触发指令’ 信号

自定义进程收到系统发出的指定信号后,将执行触发指令,而不会执行原操作

  • trap ‘’ 信号

忽略原信号的操作

  • trap -p

列出自定义信号操作
image.png

trap示例

image.png

函数

image.png

定义函数

image.png

函数使用

image.png
image.png
image.png

函数的返回值

image.png

交互环境下定义和使用函数

image.png
image.png

在脚本中定义及使用函数

image.png

使用函数文件

image.png

创建函数文件

image.png

载入函数

image.png

检查载入函数

image.png

执行shell函数

image.png

删除shell函数

image.png

函数参数

image.png

函数变量

image.png

函数递归示例

image.png
image.png

函数递归示例

image.png

fork炸弹

image.png

练习

image.png
image.png
image.png
实现效果:
image.png

image.png
实现效果:
image.png
image.png

  • 杨辉三角

数组

image.png

数组赋值

image.png

引用数组

image.png
image.png
image.png

数组数据处理

image.png

示例

image.png
image.png
image.png
image.png

练习

image.png

字符串切片

image.png
image.png
image.png

字符串处理

image.png
image.png

变量赋值

image.png

高级变量用法-有类型变量

image.png

eval命令

image.png

间接变量引用

image.png
image.png
image.png

创建临时文件

image.png

安装复制文件

image.png

expect介绍

image.png

expect命令

image.png

expect

image.png

示例

image.png
交互执行
image.png

示例:变量

image.png

示例:位置参数

image.png

示例:执行多个命令

image.png

示例:shell脚本调用expect

image.png