本章内容
- 条件判断
- 循环
- 信号捕捉
- 函数
- 数组
- 高级字符串操作
- 高级变量
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’
流程控制
- 过程式编程语言:
条件选择if语句
- 选择执行:
- 注意:if语句可嵌套
- 单分支
if 判断条件;then
条件为真的分支代码
fi
- 双分支
if 判断条件;then
条件为真的分支代码
else
条件为假的分支代码
fi
if语句
- 多分支
if 判断条件1;then
条件为真的分支代码
elif 判断条件2;then
条件为真的分支代码
elif 判断条件3;then
条件为真的分支代码
else
以上条件为假的分支代码
fi
逐条件进行判断,第一次遇到为“真”条件时,执行其分支,而后结束整个if语句
简单示例:
#!/bin/bash
#
#********************************************************************
#Author: chaitc
#Date: 2020-04-26
#FileName: test_if.sh
#Description: The test script
#Copyright (C): 2020 All rights reserved
#********************************************************************
read -p "Please input you age:" AGE
[[ "$AGE" =~ ^[0-9]+$ ]] || { echo Age is not digit; exit; }
if [ "$AGE" -lt 18 ];then
echo "good good study,day day up"
elif [ "$AGE" -ge 18 -a "$AGE" -lt 60 ];then
echo "good good work"
elif [ "$AGE" -ge 60 -a "$AGE" -lt 150 ];then
echo "good luck"
else
echo "You don't come from the earth"
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
if ping -c1 -W2 192.168.195.128 &> /dev/null;then
echo '192.168.195.128 is UP'
elif grep "192.168.195.128" ~/maintenance.txt &> /dev/null
then
echo '192.168.195.128 is undergoing mantenance '
else
echo '192.168.195.128 is unexpectedly DOWN!'
exit 1
fi
条件判断:case语句
case 变量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
…
*)
默认分支
;;
esac
case支持glob风格的通配符:
*:任意长度字符串
?:任意单个字符
[]:指定范围内的任意单个字符
a|b:a或b
练习
1、编写脚本/root/bin/createuser.sh,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id号等信息
if id $1 &> /dev/null;then
echo "you put user $1 is exists"
echo `id $1`
else
useradd $1
echo "you have created success"
echo `id $1`
fi
2、编写脚本/root/bin/yesorno.sh,提示用户输入yes或no,并判断用户输入的是yes还是no,或者其它信息
read -p "please input yes or no:" answer
case $answer in
[Yy]|[Yy][Ee][Ss])
echo "you input is yes"
;;
[Nn]|[Nn][Oo])
echo "you input is no"
;;
*)
echo "sha dou bu shi"
;;
esac
3、编写脚本/root/bin/filetype.sh,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)
/boot/grub2/ 目录 /bin 软链接 /boot/grub2/grub.cfg 普通文件
RED="\033[31m"
YELLOW="\033[0;33m"
RESET="\033[0m"
#判断参数个数
if [ $# -ne 1 ];then
echo -e "${RED}you must be enter a parameter,only one!$RESET"
exit 2
fi
case `ls -ld $1 | cut -c 1` in
-)
echo "general file"
;;
d)
echo "dir"
;;
l)
echo "link file"
;;
*)
echo "oher"
;;
esac
4、编写脚本/root/bin/checkint.sh,判断用户输入的参数是否为正整数
#判断参数个数
[ $# -eq 1 ] || { echo "please input one parameter";exit 2; }
#判断用户输入的是否正整数
if [[ $1 =~ ^[0-9]+$ ]];then
echo "is int"
else
echo "not int"
fi
循环
循环执行
将某代码重复运行多次
重复运行多少次
循环次数事先已知
循环次数事先未知
有进入条件和退出条件
循环体
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:
#for I in $(seq 10);do
# if ! id user$I &> /dev/null; then
# useradd user$I &>/dev/null
# echo "chaitc" | passwd --stdin user$I &> /dev/null
# echo "user$I add successful."
# else
# echo "user$I is exist."
# fi
#done
#方式2:
for I in {1..10};do
if id user$I &> /dev/null;then
echo "user$I is exist."
else
useradd user$I &>/dev/null
echo "chaitc" | passwd --stdin user$I &> /dev/null
echo "user$I add successful."
fi
done
批量删除临时用户:
for i in {1..10};do userdel -r user$i;done扫描网络
前台执行
net=192.168.195
for i in {1..254};do
if ping -c1 -W1 $net.$i &> /dev/null;then
echo $net.$i is up
else
echo $net.$i is down
fi
done
后台执行
net=192.168.195
for i in {1..254};do
{ if ping -c1 -W1 $net.$i &> /dev/null;then
echo $net.$i is up
else
echo $net.$i is down
fi } &
done
wait
加wait 会让后台执行退出
net=192.168.195
up=0
down=0
for i in {125..134};do
ping -c1 -W1 $net.$i &> /dev/null && { echo $net.$i is up ;let ++up; } || { echo $net.$i is down; let ++down; }
done
wait
echo up is $up
echo down is $down
打印矩阵
high=$1
width=$2
for i in `seq $high`;do
for j in `seq $width`;do
color=$[RANDOM%7+31]
echo -e "\033[1;5;${color}m*\033[0m\c"
done
echo
done
练习:用for实现
1、判断/var/目录下所有文件的类型cd /var
for i in `ls /var` ;do
case `ls -ld $i | cut -c 1` in
-)
echo "$i is general file"
;;
d)
echo "$i is dir"
;;
l)
echo "$i is link file"
;;
*)
echo "$i is oher"
;;
esac
done
7、打印九九乘法表
- 取8个随机字母
openssl rand -base64 20 | tr -dc ‘[:alpha:]’ | head -c8
- 打印象棋
while循环
- 每10秒监测一次httpd服务,如果down掉,立马重启服务,并记录日志
until循环
- 监测wang账号登录
循环控制语句continue
循环控制语句break
循环控制shift命令
- 根据用户输入参数,批量创建用户
示例:doit.sh
示例:shift.sh
创建无限循环
练习
特殊用法
- 对文本文件逐行处理,打印/etc/passwd里uid是偶数的用户名和uid
- 扫描硬盘空间利用率
特殊用法
select循环与菜单
select与case
信号捕捉trap
- trap ‘触发指令’ 信号
自定义进程收到系统发出的指定信号后,将执行触发指令,而不会执行原操作
- trap ‘’ 信号
忽略原信号的操作
- trap -p
trap示例
函数
定义函数
函数使用
函数的返回值
交互环境下定义和使用函数
在脚本中定义及使用函数
使用函数文件
创建函数文件
载入函数
检查载入函数
执行shell函数
删除shell函数
函数参数
函数变量
函数递归示例
函数递归示例
fork炸弹
练习
实现效果:
实现效果:
- 杨辉三角