目录
一、条件语句
条件语句用于根据给定条件执行不同的代码块
1、测试
1.1 测试判断
#测试判断
格式一: test 条件表达式
格式二: [条件表达式]
#文件测试
格式一: test -操作符 条件表达式
格式二: [-操作符 目录或文件]
-操作符 | 说明 |
---|---|
-d | 测试是否为目录(Directory) |
-e | 测试目录或文件是否存在(Exist) |
-a | 测试目录或文件是否存在(Exist),有点小bug,不建议使用 |
-f | 测试是否为文件(File) |
-r | 测试当前用户是否有权限读取(Read) |
-w | 测试当前用户是否有权限写入(Write) |
-x | 测试当前用户是否有权限执行(excute) |
-L | 测试是否为软连接文件 |
-t fd | 文件描述符是否在某终端已经打开 |
-N FILE | 文件自从上一次被读取之后是否被修改过 |
-O FILE | 当前有效用户是否为文件属主 |
-G FILE | 当前有效用户是否为文件属组 |
-s FILE | 是否存在且非空 |
注:
判断该脚本是否有读取权限,是以实际效果为主而不是表面的显示,需要注意root权限
其他所有用户没有执行权限则root也没有执行权限,只要有一个用户有执行权限那么root用户也会拥有执行权限
注:
-e 选项和 -a 选项的区别:
-a选项在取反即使用 ! 有bug,所以不建议使用-a选项来检测文件或目录是否存在,建议用-e选项
1.2 关系运算符(比较整数数值)
[ 整数1 -操作符 整数2 ]
关系运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true | [ $a -eq $b ] 返回 false |
-ne | 检测两个数是否不相等,不相等返回 true | [ $a -ne $b ] 返回 true |
-gt | 检测左边的数是否大于右边的,如果是返回 true | [ $a -gt $b ] 返回 false |
-lt | 检测左边的数是否小于右边的,如果是则返回 true | [ $a -lt $b ] 返回 true |
-ge | 检测左边的数是否大于等于右边的,如果是则返回 true | [ $a -ge $b ] 返回 false |
-le | 检测左边的数是否小于等于右边的,如果是则返回 true | [ $a -le $b ] 返回 true |
1.3 字符串比较
[ 整数1 -操作符 整数2 ]
字符串比较运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true | [ $a = $b ] 返回 false |
!= | 检测两个字符串是否不相等,不相等返回 true | [ $a != $b ] 返回 true |
-z | 检测字符串长度是否为0,为0返回 true | [ -z $a ] 返回 false |
-n | 检测字符串长度是否不为 0,不为 0 返回 true | [ -n "$a" ] 返回 true |
$ | 检测字符串是否不为空,不为空返回 true | [ $a ] 返回 true |
[ 字符串1 = 字符串2 ] 字符串1与字符串2是否相同
[ 字符串1 != 字符串2 ] 字符串1与字符串2是否不相同
[ -z 字符串 ] 字符串是否为空
[ -n 字符串 ] 字符串是否存在
1.4 逻辑测试(短路运算)
格式1: [ 表达式1 ] 操作符 [ 表达式2 ] ...
格式2: 命令1 操作符 命令2 ...
布尔运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true | [ ! false ] 返回 true |
-o | 或运算,有一个表达式为 true 则返回 true | [ $a -lt 20 -o $b -gt 100 ] 返回 true |
-a | 与运算,两个表达式都为 true 才返回 true | [ $a -lt 20 -a $b -gt 100 ] 返回 false |
逻辑操作符 | 说明 |
---|---|
&& | 逻辑与,“而且”的意思全真才为真,一假即假 |
|| | 逻辑或,“或者”的意思一真即为真,一真即真 |
&&与||结合使用,一般只有以下一种用法
cmd1 && cmd2 || cmd3
该语句会有两种输出情况:
①cmd1的条件如果为真,就会执行cmd2的条件,那么整个式子一定为真,就不需要执行cmd3的条件
②cmd1的条件如果为假,就不需要执行cmd2的条件,因为这时(cmd1 && cmd2)整个为假,那么则需要执行cmd3的条件
案例一:
使用ping命令检测主机网络联通性
#!/bin/bash
ping -c2 $1 &>/dev/null && echo "$1 is online" || echo "$1 is offline"
#使用ping命令检测主机的联通性,如果能ping通则返回"&1 is online",不能ping通则返回"$1 is offline"
亦可以用if语句实现
#!/bin/bash
ping -c2 -W2 172.16.12.10
if
[ $? = 0 ]
then
echo "该主机网络通顺"
exit 1
fi
echo "该主机网络不通"
案例二:
#!/bin/bash
use=`df|tr -s " "|grep sda|cut -d " " -f5|tr -d %`
[ $use -ge 80 ] && echo "磁盘使用量过高" | mail -s warning 3487547879@qq.com || echo "磁盘剩余量足够"
#当磁盘使用量超过80%时,会发送邮件到QQ邮箱警示你,当磁盘使用量小于80%,执行脚本会回复你“磁盘剩余量足够”
1.5 双中括号的用法
双中括号 [[ ... ]]
通常用于条件测试和比较操作。它们提供了更多的功能和灵活性,相较于单中括号 [ ... ]
特殊情况:
当使用 `==' 和 `!=' 操作符时,操作符右边的字符串被用作模式并且执行一个匹配,即支持通配符
当使用 `=~' 操作符时,操作符右边的字符串被当作正则表达式来进行匹配
[[ $file == *.log ]] = [[ $file =~ log$ ]]
1.6 () 与 {} 的用法及区别
(CMD1 ; CMD2;... ;)和 { CMD1 ; CMD2 ; ... ; } 都可以将多个命令组合成一个整体,作为单个命令执行
区别 | 说明 |
---|---|
(CMD1 ; CMD2;... ;) | 开启子shell去执行命令,这也意味着括号内的变量更改不会影响到父shell |
{ CMD1 ; CMD2 ; ... ; } | 使用当前shell去执行命令,可能会影响当前shell的环境 |
1.7 括号组合使用的区别
- [[ ]]只能使用&& ||,不能使用-a或-o。&&和||写在括号里或外都可以
- (( ))与[[ ]]相同,只不过可以省略变量前的$,且只能用于整数比较
- [ ]既可以使用&& ||,也可以使用-a或-o。但&&和||必须在括号外,-a或-o必须在括号内
括号内连接 | 括号外连接 | |
---|---|---|
[ ] | -a -o | && || |
[[ ]] | && || | && || |
2、if语句
2.1 单分支if语句
单分支if语句只包含一个条件,如果条件为真,则执行相应的代码块;否则跳过
#单分支if语句格式:
if 判断条件;
then
条件为真的分支代码
fi
2.2 双分支if语句
双分支if语句包含两个分支,一个是条件为真时执行的代码块,另一个是条件为假时执行的代码块
#双分支if语句格式:
if 判断条件;
then
条件为真的分支代码
else
条件为假的分支代码
fi
2.3 多分支if语句
多分支if语句使用elif
关键字来测试多个条件,并在找到第一个为真的条件时执行相应的代码块
#多分支if语句格式:
if 判断条件1
then
条件1为真的分支代码
elif 判断条件2
then
条件2为真的分支代码
elif 判断条件3
then
条件3为真的分支代码
......
else
以上条件都为假的分支代码
fi
2.4 shell脚本的if语句案例
案例一
编写脚本检查httpd服务是否开启,如果开启则反馈httpd服务正在运行,否则启动httpd服务
#!/bin/bash
#检查httpd服务是否开启,如果开启则反馈httpd服务正在运行,否则启动httpd服务
systemctl status httpd &> /dev/null
if [ $? -eq 0 ]
then
echo "httpd 服务正在运行"
else
systemctl start httpd
if [ $? -eq 0 ]
then
echo "httpd 服务正常启动"
else
echo "httpd 服务异常,启动失败"
fi
fi
案例二
编写脚本实现安装httpd服务,先判断操作系统的类型,如果是centos系统则使用yum命令安装httpd,如果是ubuntu系统则使用apt命令安装httpd,其他暂不支持
#!/bin/bash
#编写脚本实现安装httpd服务,先判断操作系统的类型,如果是centos系统则使用yum命令安装httpd,如果是ubuntu系统则使用apt命令安装httpd,其他暂不支持
if grep -q centos /etc/os-release
then
yum install httpd -y &>/dev/null
if [ $? -eq 0 ]
then
echo "httpd服务安装成功!"
else
echo "httpd服务安装失败!请检查错误!"
fi
elif grep -q ubuntu /etc/os-release
then
apt install httpd -y &>/dev/null
if [ $? -eq 0 ]
then
echo "httpd服务安装成功!"
else
echo "httpd服务安装失败!请检查错误!"
fi
else
echo "您的操作系统暂不支持安装httpd服务!"
fi
案例三
判断当前用户是否为超级管理员
#!/bin/bash
#判断当前用户是否为超级管理员
if [ "$USER" != "root" ]
then
echo "非管理员用户无权限操作"
else
echo "您是管理员用户"
fi
案例四
请输入分数,来判断成绩的优良
#!/bin/bash
#请输入分数,来判断成绩的优良
#优秀:90~100分 良好:70~89分 60-69 及格:60~69分 不及格:0~59 分数输入错误可重新输入
read -p "请输入你的分数(0~100):" score
if [ $score -ge 90 -a $score -le 100 ];then
echo "优秀"
elif [ $score -ge 70 -a $score -le 89 ];then
echo "良好"
elif [ $score -ge 60 -a $score -le 69 ];then
echo "及格"
elif [ $score -ge 0 -a $score -le 59 ];then
echo "不及格"
else
echo "输入有误!请重新输入分数!"
bash $0
fi
案例五
编写脚本,根据当前时间打印不同的问候语
#!/bin/bash
#编写脚本,根据当前时间打印不同的问候语
h=`date +%H`
if [ $h -ge 6 -a $h -le 10 ];then
echo "早上好"
elif [ $h -ge 11 -a $h -le 13 ];then
echo "中午好"
elif [ $h -ge 14 -a $h -le 18 ];then
echo "下午好"
else
echo "晚上好"
fi
案例六
编写脚本实现石头剪刀布的游戏
#!/bin/bash
read -p "请输入 1(石头) 2(剪刀) 3(布):" h
m=`echo $[RANDOM%3+1]`
if [ $h -eq $m ]
then
echo "平局!"
elif [ $h -eq 1 -a $m -eq 2 -o $h -eq 2 -a $m -eq 3 -o $h -eq 3 -a $m -eq 1 ];then
echo "您赢了!"
else
echo "您输了!"
fi
案例七
检测系统的用户状态是否正常,有用户也有家目录视为正常,有用户但是没家目录为无用户,其他没有用户则视为该用户不存在
#!/bin/bash
read -p "请输入用户名:" user
sh=`grep $user /etc/passwd | cut -d : -f6`
if grep $user /etc/passwd &>/dev/null
then
if [ -e $sh ];then
echo "该用户状态正常"
else
read -p "该用户没有家目录,是否删除该用户,请输入[yes/no]:" ask
if [ $ask == yes ];then
echo "正在删除用户……"
userdel $user &>/dev/null
echo "该用户已删除"
elif [ $ask == no ];then
exit
fi
fi
else
echo "该用户不存在!"
fi
3、case语句
3.1 case语句格式
case
语句是一种条件语句,用于检查变量或数值等表达式的取值,并根据这些值执行相应的命令或代码块
case格式:
case 变量值 in
模式1)
分支1
;;
PAT2)
分支2
;;
......
*) #支持通配符:*、?、[0-9]、|
默认分支
esac
3.2 shell脚本的case语句案例
案例一
判断输入的是 yes(y,Y,Yes,yEs,yeS,YEs,YeS,yES,YES) 或者 no(N,n,no,No,nO,NO)
方法一:
#!/bin/bash
#判断输入的是 yes(y,Y,Yes,yEs,yeS,YEs,YeS,yES,YES) 或者 no(N,n,no,No,nO,NO)
read -p "请输入 yes 或 no :" i
case $i in
[yY]|[yY][eE][sS])
echo "您输入的是:yes"
;;
[nN]|[nN][oO])
echo "您输入的是:no"
;;
*)
echo "您输入有误请重新输入 yes 或 no"
bash $0
esac
方法二:
#!/bin/bash
#(y,Y,Yes,yEs,yeS,YEs,YeS,yES,YES) 或者 no(N,n,no,No,nO,NO)
read -p "请输入 yes 或 no :" i
num=`echo $i|tr 'A-Z' 'a-z'`
case $num in
y|yes)
echo "您输入的是:yes"
;;
n|no)
echo "您输入的是:no"
;;
*)
echo "您输入有误请重新输入 yes 或 no"
bash $0
esac
案例二
请输入分数,来判断成绩的优良
#!/bin/bash
#请输入分数,来判断成绩的优良
#优秀:90~100分 良好:70~89分 60-69 及格:60~69分 不及格:0~59 分数输入错误可重新输入
read -p "请输入你的分数(0~100):" score
case $score in
[99][0-9]|100)
echo "$score 成绩优秀"
;;
[89][0-9])
echo "$score 成绩良好"
;;
[67][0-9])
echo "$score 成绩合格"
;;
[0-9]|[1-5][0-9])
echo "$score 成绩不合格"
;;
*)
echo "输入有误!请重新输入分数!"
esac
案例三
编写工具箱,即通过不同的选项可以查看不同的系统信息
#!/bin/bash
cat <<EOF
----------------------------------------
|1.查看系统类型
|2.查看主机名
|3.IP地址
|4.查看磁盘大小
|5.查看内存
|6.查看内核版本
|7.查看CPU型号
|8.退出工具箱
----------------------------------------
EOF
read -p "请输入(1~8)选项:" num
case $num in
1)
cat /etc/redhat-release
echo "------------------------------------"
echo
bash $0
;;
2)
hostname
echo "------------------------------------"
echo
bash $0
;;
3)
ifconfig ens33 | grep netmask | tr -s " " | cut -d " " -f3
echo "------------------------------------"
echo
bash $0
;;
4)
lsblk | grep disk | awk '{print $4}'
echo "------------------------------------"
echo
bash $0
;;
5)
free
echo "------------------------------------"
echo
bash $0
;;
6)
uname -r
echo "------------------------------------"
echo
bash $0
;;
7)
lscpu | grep 型号名称 | tr -s " " | cut -d" " -f2-8
echo "------------------------------------"
echo
bash $0
;;
8)
exit
echo "------------------------------------"
echo
bash $0
;;
esac
案例四
编写脚本实现石头剪刀布的游戏,需显示双方出的结果和输赢情况
#!/bin/bash
key=`echo $[RANDOM%3+1]`
read -p "请输入 1(石头) 2(剪刀) 3(布):" num
case $num in
1)
num="石头"
;;
2)
num="剪刀"
;;
3)
num="布"
;;
*)
echo "您输入错误!请重新输入!"
exit
;;
esac
case $key in
1)
key="石头"
;;
2)
key="剪刀"
;;
3)
key="布"
;;
esac
if [ $num = "石头" -a $key = "剪刀" -o $num = "剪刀" -a $key = "布" -o $num = "布" -a $key = "石头" ]
then
echo "机器出的是:$key"
echo "您出的是:$num"
echo "您赢了!"
elif [ $num = $key ]
then
echo "机器出的是:$key"
echo "您出的是:$num"
echo "平局!"
else
echo "机器出的是:$key"
echo "您出的是:$num"
echo "您输了!"
fi
案例五
编写脚本实现点餐
#!/bin/bash
sum=0
PS3="请输入(1-6):"
MENU="
酸菜鱼
佛跳墙
东坡肉
鱼香肉丝
宫保鸡丁
点餐结束
"
select menu in $MENU
do
case $REPLY in
1)
echo "$menu 价格是:68"
let sum+=68
;;
2)
echo "$menu 价格是:50"
let sum+=50
;;
3)
echo "$menu 价格是:25"
let sum+=25
;;
4)
echo "$menu 价格是:22"
let sum+=22
;;
5)
echo "$menu 价格是:38"
let sum+=38
;;
6)
echo "点菜结束"
break
;;
*)
echo "点菜错误,请重新选择"
;;
esac
done
echo "总价是$sum"