判断和循环

条件测试

  • 为命令的执行提供最直接的识别依据
    • 文件或目录的读/写等状态
    • 数值的大小
    • 字符串是否匹配
    • 多条件组合

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"
最后更新时间:
贡献者: DESKTOP-ER5718D\zt