判断和循环
条件测试
- 为命令的执行提供最直接的识别依据
- 文件或目录的读/写等状态
- 数值的大小
- 字符串是否匹配
- 多条件组合
test测试操作
- 语法格式
test 选项 参数
- [ 选项 参数 ]
help test
查阅帮助
字符串比较
- 基本语法
- 是否为空
[ -z 字符串 ]
- 等于
[ 字符串1 == 字符串2 ]
- 不等于
[ 字符串1 !== 字符串2 ]
- 是否为空
[ -z $a ]
echo $? # 0
a=123
[ -z $a ]
echo $? # 1
整数值比较
[ 整数值1 操作符 整数值2 ]
操作符 | 含义 |
---|---|
-eq | 等于(Equal) |
-ne | 不等于(Not Equal) |
-ge | 大于或等于(Greater or Equal) |
-le | 小于或等于(Less or Equal) |
-gt | 大于(Greater Equal) |
-lt | 小于(Less Equal) |
[ 3 -eq 3 ]
echo $? # 0
ls | wc -l # 10 返回文件个数
[ $(ls | wc -l) -le 5 ]
echo $? # 1
文件状态测试
[ 操作符 文件或目录 ]
操作符 | 含义 |
---|---|
-e | 判断对象是否存在(Exist),若存在则结果为真 |
-d | 判断对象是否为目录(Directory),是则为真 |
-f | 判断对象是否为一般文件(File),是则为真 |
-r | 判断对象是有可读(Read)权限,是则为真 |
-w | 判断对象是有可写(Write)权限,是则为真 |
-x | 对象是否有可执行(eXcute)权限,是则为真 |
[ -e /etc ]
echo $? # 0
[ -f /etc ]
echo $? # 1
组合多个命令
- 使用控制符组合多个命令
;
分割执行命令&&
并且,在前置命令执行成功后才能之后后置命令||
或者,优先执行前置命令,前置命令执行失败后执行后置命令
cd usr/ ; ls
# bin/ etc/ lib/ libexec/ share/ ssl/
cd usr/ && ls
# bin/ etc/ lib/ libexec/ share/ ssl/
cd usr错误目录/ || echo message
# message
多条件判断
- 使用&&、||进行多个条件的判断
[ 判断1 ] && [ 判断2 ]
[ 判断1 ] || [ 判断2 ]
[[ 判断1 && 判断2 || 判断3 ]]
if 语句
if 单分支语法
- 当“条件成立”时执行命令序列
- 否则,不执行任何操作
if 条件测试
then 命令序列
fi
if 条件测试;then
命令序列
fi
下方有示例
if 双分支判断
- 当“条件成立”时执行命令序列1
- 否则,执行命令序列2
if 条件测试
then
命令序列1
else
命令序列2
fi
if 条件测试;then
命令序列1
else
命令序列2
fi
下方有示例
if 多分支判断
- 相当于if语句嵌套
- 针对多个条件分别执行不同的操作
if 条件测试1;then
命令序列1
elif 条件测试2;then
命令序列2
... ...
else
命令序列n
fi
下方有示例
for 循环
- 根据变量的不同取值,重复执行命令序列
for 变量 in 值列表
do
命令序列
done
for ((初值;条件;步长;))
do
命令序列
done
for i in 1 8 ab 99 qq
do
echo -n " I am $i"
done
# I am 1 I am 8 I am ab I am 99 I am qq
for ((i=1;i<=5;i++))
do
echo -n " I am $i"
done
# I am 1 I am 2 I am 3 I am 4 I am 5
下方有示例
while 循环
- 反复测试条件,只要成立就执行命令序列
while 条件测试
do
命令序列
done
while 未猜中正确价格
do
反复猜商品价格
done
# 正常循环
i=1
while [ $i -le 5 ]
do
echo $i
let i++ # 递增控制,避免死循环
done
# 无限循环 “:”
while :
do
echo hello world
done
下方有示例
示例
监控脚本
#!/bin/bash
# 获取系统各项性能参数指数,并与预设阈值进行比较
local_time=$(date +"%Y%m%d %H:%M:%S") # 获取时间
local_ip=$(ifconfig ens33 | grep netmask | tr -s " " | cut -d" " -f3) # 获取ens33网卡IP
free_mem=$(cat /proc/meminfo | grep Avai | tr -s " " | cut -d" " -f2) # 获取剩余内存大小
free_disk=$(df | grep "\$" | tr -s " " | cut -d" " -f4) # 获取剩余磁盘大小
cpu_load=$(cat /proc/loadavg | cut -d" " -f3) # 获取工作负载
login_user=$(who | wc -l) # 获取登录系统用户
procs=$(ps aux | wc -l) # 获取当前进程数
# 当剩余内存不足1GB时发送邮件给root进行报警
[ $free_mem -lt 1048576 ] && echo "$local_time 可用内存不足,可用内存:$free_mem 在 $local_ip 机器" | mail -s 警告 root@localhost
# 当剩余磁盘不足10GB时发送邮件给root进行报警
[ $free_disk -lt 10485760 ] && echo "$local_time 可用磁盘不足,可用内存:$free_disk 在 $local_ip 机器" | mail -s 警告 root@localhost
# 当剩CPU 15min 平均负载超过4时发送邮件给root进行报警,因为包含小数所以使用bc
result=$(echo "$cpu_load > 4" | bc)
[ $result -eq 1 ] && echo "$local_time CPU负载过高,CPU负载:$cpu_load 在 $local_ip 机器" | mail -s 警告 root@localhost
# 当剩实时在线人数大于3人时发送邮件给root进行报警
[ $login_user -gt 3 ] && echo "$local_time 登录用户过多,$login_user 登录在 $local_ip 机器" | mail -s 警告 root@localhost
# 当剩实时进程数大于50时发送邮件给root进行报警
[ $procs -gt 50 ] && echo "$local_time 进行执行过多,$procs 执行在 $local_ip 机器" | mail -s 警告 root@localhost
新增用户密码(if 单分支语法)
#!/bin/bash
# 新增用户密码(if 单分支语法)
read -p "请输入用户名:" user
read -s -p "请输入密码:" pass
if [ ! -z "$user" ]&&[ ! -z "$pass" ];then
useradd "$user"
echo "$pass" | passwd --stdin "$user"
fi
echo
ping主机(if 双分支判断)
#!/bin/bash
# ping主机(if 双分支判断)
if [ -z "$1" ];then
echo -n "用法:脚本"
echo -e "\033[32m域名或IP\033[0m"
exit
fi
ping -c2 -i0.1 -W1 "$1" &>/dev/null
if [ $? -eq 0 ];then
echo "$1 能够ping通"
else
echo "$1 不能够ping通"
fi
猜随机数(if 多分支判断)
#!/bin/bash
# 脚本自动生成10以内的随机数,根据用户的输入,输出判断结果。(每次脚本执行只能猜一次)
clear
num=$[RANDOM%10+1]
read -p "请输入1-10之间的整数:" guess
if [ $geuss -eq $num ];then
echo "恭喜猜对了就是:$num"
elif [ $geuss -lt $num ];then
echo "猜小了"
else
echo "猜大了"
fi
循环创建系统账户(for 循环)
#!/bin/bash
# 循环创建系统账户(for 循环)
for i in {1..10}
do
useradd test$i
echo "123456" | passwd --stdin test$i
done
批量创建系统账户(for 循环)
user.txt
huang
jin
liang
#!/bin/bash
# 批量创建系统账户(for 循环)
for i in $(cat user.txt)
do
useradd "$i"
echo "123456" | passwd --stdin "$i"
done
9*9乘法表(for 循环)
#!/bin/bash
# 9*9乘法表(for 循环)
for ((i=1;i<=9;i++))
do
for ((j=1;j<=i;j++))
do
echo -n " $i*$j=$[i*j] "
done
echo
done
循环创建系统账户(while 循环)
#!/bin/bash
# 循环创建系统账户(while 循环)
PREFIX="tuser" ; i=1
while [ $i -le 5 ]
do
useradd ${PREFIX}$i
echo "123456" | passwd --stdin ${PREFIX}$i &> /dev/null
let i++
done
猜随机数(while 循环)
#!/bin/bash
# 脚本自动生成10以内的随机数,根据用户的输入,输出判断结果(可猜多次)
num=$[RANDOM%10+1]
while :
do
read -p "请输入1-10之间的整数:" guess
if [ $geuss -eq $num ];then
echo "恭喜猜对了就是:$num"
exit # 猜中后结束脚本
elif [ $geuss -lt $num ];then
echo "猜小了"
else
echo "猜大了"
fi
done
一键部署FTP服务
#!/bin/bash
# 安装 vsftpd 软件,修改配置文件,设置匿名用户上传文件
if rpm -q vsfitd &> /dev/numm;then
echo "vsfitd已安装"
else
yum -y install vsfitd
fi
systemctl restart vaftpd
监控网络流量
#!/bin/bash
# 监控网络流量
while :
do
clear
echo '本地网卡eth0流量信息如下:'
ifconfig eth0 | grep "RX pack" | tr -s" " | cut -d" " -f6
ifconfig eth0 | grep "TX pack" | tr -s" " | cut -d" " -f6
sleep 1
done
统计闰年
#!/bin/bash
# 判断有序的数字是否是闰年
# 条件1:能被4整除但不能被100整除。条件2:能被400整除。
# 满足条件1或条件2之一就是闰年
for i in {2000..5000}
do
if [[ $[i%4] -eq 0 && $[i%100] -ne 0 || $[i%400] -eq 0 ]];then
echo "$i:是闰年"
else
echo "$i:非闰年"
fi
done
计算等差数列之和
#!/bin/bash
# 计算等差数列之和1+2+3+4+5,...,+100
sum=0;i=1
while [ $i -le 100 ]
do
let sum+=$i
let i++
done
echo -e "1+2+3+4+5,...,+100的总和为:\033[1;32m$sum\033[0m"