本章结构:
- 条件测试
- 文件测试与整数测试
- 字符串测试与逻辑测试
- if语句
- if单分支语句
- if双分支语句
- if多分支语句
- case分支语句
一、 条件测试
1. 文件测试
文件测试格式:
格式一: `test 操作符 表达式`
test命令用来测试表达式是否成立,若成立返回0,否则返回其他数值
格式二:` [ 操作符 表达式 ] `
注意前后空格,否则会失败
测试是否成功使用 `echo $?` 返回值
操作符:
| 操作符 | 作用 |
|---|---|
| -d | 测试是否为目录(Directory) |
| -e | 测试目录或文件是否存在(Exist) 建议使用-e |
| -a | 测试目录或文件是否存在(Exist) |
| -f | 测试是否为文件(File) |
| -r | 测试当前用户是否有权限读取(Read) |
| -w | 测试当前用户是否有权限写入(Write) |
| -x | 测试当前用户是否有权限执行(eXcute) |
| -L | 测试是否为软连接文件 |
例1:`-d`
[root@node1 ~]# test -d /var/ //测试/var/是否为目录
[root@node1 ~]# echo $?
0 //状态码返回0,表示为真,是目录
[root@node1 ~]# [ -d /var ]
[root@node1 ~]# echo $?
0
例2:`-f`
[root@node1 ~]# test -f /var/ //测试/var/是否为文件
[root@node1 ~]# echo $?
1 //状态码返回1,表示为假,不是目录
例3:`-e`和`-a`
[root@node1 ~]# [ -e /var/log ] //-e测试文件是否存在
[root@node1 ~]# echo $?
0
[root@node1 ~]# [ -a /var/log ] //-a测试文件是否存在
[root@node1 ~]# echo $?
0
[root@node1 ~]# [ ! -e /var/log ];echo $? //! -e 测试文件是否不存在
1
[root@node1 ~]# [ ! -a /var/log ];echo $? //! -a 测试文件是否不存在
0 //判断结果有误
-e和-a都可以测试文件是否存在,但和 !(取反)连用时,-a可能不准确,建议使用-e
例4:`-r`、`-w`、`-x`
测试root用户对文件是否拥有读、写、执行权限:
[root@node1 ~]# ll /etc/shadow
----------. 1 root root 1339 3月 6 10:43 /etc/shadow
[root@node1 ~]# [ -r /etc/shadow ];echo $? //测试root用户对文件是否拥有读权限
0
[root@node1 ~]# [ -w /etc/shadow ];echo $? //测试root用户对文件是否拥有写权限
0
[root@node1 ~]# [ -x /etc/shadow ];echo $? //测试root用户对文件是否拥有执行权限
1
发现root用户的读取和写入权限,不受文件的基本权限控制;但执行权限受文件基本权限控制。
2. 整数值比较
格式 :[ 整数变量1 操作符 整数变量2 ]
常用的测试操作符:
| 操作符 | 含义 |
|---|---|
| -eq | 第一个数等于(Equal)第二个数 |
| -ne | 第一个数不等于(Not Equal)第二个数 |
| -gt | 第一个数大于(Greater Than)第二个数 |
| -lt | 第一个数小于(Lesser Than)第二个数 |
| -ge | 第一个数大于或等于(Greater or Equal)第二个数 |
| -le | 第一个数小于或等于(Lesser or Equal)第二个数 |
[root@node1 ~]# a=10
[root@node1 ~]# b=20
[root@node1 ~]# [ $a -lt $b ] //a 小于 b
[root@node1 ~]# echo $? //测试是否正确
0 //正确
[root@node1 ~]# [ $a -gt $b ] //a 大于 b
[root@node1 ~]# echo $? //测试是否正确
1 //错误
3. 字符串测试
常用格式:
`[ 字符串1 = 字符串2 ]` 测试字符串1和字符串2的内容是否相同
`[ 字符串1 != 字符串2 ]` 测试字符串1和字符串2的内容是否不同
常用的测试操作符:
| 操作符 | 含义 |
|---|---|
| = | 字符串内容相同 |
| != | 字符串内容不同,! 号表示相反的意思 |
| -z | 字符串内容为空 |
| -n | 字符是否存在 |
4. 逻辑测试
逻辑测试用于连接多个测试条件,并返回整个表达式的值。 逻辑测试主要有"逻辑与","逻辑或","逻辑否"三种。
格式 :
格式1:`[ 表达式1 ] 操作符 [ 表达式2 ] ... `
格式2:`命令1 操作符 命令2 ...`
常用的测试操作符:
-a或&&:逻辑与,“而且”的意思,全真才为真。-o或||:逻辑或,“或者”的意思,一真即为真。!:逻辑否。
唯一的组合用法:cmd1 && cmd2 || cmd3
短路与 &&
CMD1 && CMD2
全真才为真,一假即为假。
第一个CMD1结果为真 ,第二个CMD2必须要参与运算,才能得到最终的结果。
第一个CMD1结果为假 ,总的结果必定为假,因此不需要执行CMD2。
同时满足命令1 和命令2 的要求,才会返回正确。
短路或 ||
CMD1 || CMD2
一真即为真
第一个CMD1结果为真,总的结果必定为真,因此不需要执行CMD2。
第一个CMD1结果为假,第二个CMD2必须要参与运算,才能得到最终的结果。
5. 双中括号 [[ ]]
[[ expression ]] 用法:
==左侧字符串是否和右侧的PATTERN相同- 注意:此表达式用于[[ ]]中,PATTERN为
=~左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配- 注意: 此表达式用于[[ ]]中;扩展的
6. ()和 {}
(CMD1;CMD2;...)和 { CMD1;CMD2;...; } 都可以将多个命令组合在一起,批量执行
`()`会开启子shell
`{ }` 不会开启子shell
[root@localhost data]#name=lc
[root@localhost data]#( name=mcl;echo $name );echo $name
lc
[root@localhost data]#name=lc
[root@localhost data]#{ name=mcl;echo $name; };echo $name
mcl
二、if 语句
1. 单分支结构
单分支语句格式:
if 条件判断的cmd
then
条件为真的分支代码cmd1
fi //条件不成立直接结束
#执行条件判断的cmd,如果cmd成功执行,那么就运行cmd1,否则退出
2. 双分支结构
双分支语句格式:
if 判断条件cmd1
then
条件为真的分支代码cmd2
else
条件为假的分支代码cmd3
fi
#cmd1成功,执行cmd2,否则执行cmd3
示例:
例1:判断内存容量
[root@node1 ~]# vim mem.sh //编写脚本
#!/bin/bash
mem=`free -m |grep Mem |awk ‘{print $4}’` //awk命令默认以空格为分隔符,print $4打印第四列
if [$mem -lt 300 ];then //判断条件:内存小于300MB
echo "内存不足,请尽快处理" //条件为真输出 内存不足,请尽快处理
echo 3 > /proc/sys/vm/drop caches //清理缓存
else
echo "内存正常" //条件为假输出 内存正常
fi
[root@node1 ~]# bash mem.sh //执行脚本
内存不足,请尽快处理
例2:判断httpd是否存在
[root@node1 ~]# vim h.sh //编写脚本
#!/bin/bash
if command -v httpd &>/dev/null;then //&>/dev/null 垃圾信息导入黑洞
echo "httpd已安装"
else
echo "httpd 未安装"
yum install&>/dev/null httpd-V
if [ $? -eq 0 ];then //嵌套
echo "httpd 成功安装"
systemctl start httpd
if [ $? -eq 0 ];then //再嵌套
echo "启动成功"
else
echo "启动失败"
fi
else
echo "httpd安装失败,请检查"
fi
fi
[root@node1 ~]# bash h.sh //执行脚本
httpd已安装
3. 多分支结构
双分支语句格式:
if 判断条件1
then
条件1为真的分支代码
elif 判断条件2
then
条件2为真的分支代码
elif 判断条件3
then
条件3为真的分支代码
......
else
以上条件都为假的分支代码
fi
示例:
[root@node1 ~]# vim grade.sh //编写脚本
#!/bin/bash
read -p "请输入你的考试分数:" grade
if [ $grade -ge 85 ]&& [ $grade -le 100 ] //分数大于等于85,小于等于100
then
echo "你的成绩为$grade"
echo "你的成绩为优秀"
elif [ $grade -ge 70 ]&&[ $grade -le 84 ] //分数大于等于70,小于等于84
then
echo "你的成绩为$grade"
echo "你的成绩为良好"
elif
[ $grade -ge 60 ]&&[ $grade -le 69 ] //分数大于等于60,小于等于69
then
echo "你的成绩为$grade"
echo "你的成绩为合格"
else //以上条件都为假
echo "你的成绩为$grade"
echo "你的成绩不合格"
fi
[root@node1 ~]# bash grade.sh //执行脚本
请输入你的考试分数:88
你的成绩为88
你的成绩为优秀
三、 case 语句
语句格式:
case 变量值 in
模式1)
命令分支1
;;
模式2)
命令分支2
;;
...
*)
默认命令分支
esac
case支持glob风格的通配符:
* 任意长度任意字符
? 任意单个字符
[0-9] 指定范围内的任意单个字符
| 或者,如: a|b
示例1:远程连接(跳板机)
[root@localhost ~]# vim tbj.sh //编写脚本
#!/bin/bash
web1="192.168.204.10"
mysql="192.168.204.20"
docker="192.168.204.30"
cat <<EOF //打印菜单
1.web1
2.mysql
3.doker
EOF
read -p "请输入数字(1-3):" num
case $num in
1)
ssh $web1
;;
2)
ssh $mysql
;;
3)
ssh $doker
;;
*)
echo "输入有误,请重新输入"
bash $0
esac
[root@localhost ~]# bash tbj.sh //执行脚本
1.web1
2.mysql
3.doker
请输入数字(1-3):4
输入有误,请重新输入
1.web1
2.mysql
3.doker
请输入数字(1-3):1 //远程登录web1
The authenticity of host '192.168.204.10 (192.168.204.10)' can't be established.
ECDSA key fingerprint is SHA256:NGL8rGGG53cTly5n3T2ZebgIfifyVkSu9C96Jx1GFfI.
ECDSA key fingerprint is MD5:a6:df:04:3b:65:de:68:2d:a2:dd:27:26:1f:de:ef:9c.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.204.10' (ECDSA) to the list of known hosts.
root@192.168.204.10's password:
Last login: Sun May 12 11:02:42 2024 from 192.168.204.1 //成功登录web1
[root@node1 ~]# exit
登出
Connection to 192.168.204.10 closed.
示例2:判断成绩等级
[root@node1 ~]# vim score.sh //编写脚本
#!/bin/bash
read -p "请输入你的分数" score
case $score in //$score变量值
100) //100分
echo "$score 你太优秀了"
;;
[89][0-9]) //80~99分 (第一位数为8或9,第二位为0-9任意一位)
echo "$score 表现不错"
;;
[67][0-9]) //60~79分
echo "$score 你及格了"
;;
[0-9]|[1-5][0-9]) //个位数 或者 10~59分
echo "$score 你不及格"
;;
*)
echo "输入有误"
esac
[root@node1 ~]# bash score.sh //执行脚本
请输入你的分数88
88 表现不错
[root@node1 ~]# bash score.sh
请输入你的分数101
输入有误
示例3:判断输入的是yes或no
无论多奇怪的yes或no都可以识别
[root@node1 ~]# vim yes.sh //编写脚本
#!/bin/bash
read -p "Do you agree(yes/no)? " INPUT
INPUT=`echo $INPUT | tr 'A-Z' 'a-z'` //转换大小写
case $INPUT in
y|yes)
echo "You input is YES"
;;
n|no)
echo "You input is NO"
;;
*)
echo "Input fales,please input yes or no!"
esac
[root@node1 ~]# bash yes.sh //执行脚本
Do you agree(yes/no)? Yes
You input is YES
[root@node1 ~]# bash yes.sh
Do you agree(yes/no)? nO
You input is NO
示例4:工具箱
[root@localhost ~]# vim gjx.sh //编写脚本
#!/bin/bash
cat <<EOF //打印菜单工具
----系统工具箱------------
| 1.查看磁盘信息 |
| 2.查看内存信息 |
| 3.查看cpu 信息 |
| 4.查看网络信息 |
| 5.查看进程信息 |
| 6.退出工具箱 |
----系统工具箱------------
EOF
read -p "请输入您的选择(1-6)" num
case $num in
1)
lsblk
bash $0
;;
2)
free
bash $0
;;
3)
lscpu
bash $0
;;
4)
ifocnfig
bash $0
;;
5)
ps aux
bash $0
;;
6)
exit
;;
esac
[root@localhost ~]# bash gjx.sh //执行脚本
----系统工具箱------------
| 1.查看磁盘信息 |
| 2.查看内存信息 |
| 3.查看cpu 信息 |
| 4.查看网络信息 |
| 5.查看进程信息 |
| 6.退出工具箱 |
----系统工具箱------------
请输入您的选择(1-6)1 //查看磁盘信息
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 40G 0 disk
├─sda1 8:1 0 1G 0 part /boot
└─sda2 8:2 0 14G 0 part
├─centos-root 253:0 0 10G 0 lvm /
└─centos-swap 253:1 0 4G 0 lvm [SWAP]
sr0 11:0 1 1024M 0 rom
----系统工具箱------------
| 1.查看磁盘信息 |
| 2.查看内存信息 |
| 3.查看cpu 信息 |
| 4.查看网络信息 |
| 5.查看进程信息 |
| 6.退出工具箱 |
----系统工具箱------------
请输入您的选择(1-6)6 //退出
示例5:nginx安装
[root@localhost ~]# vim nginx.sh //编写脚本
#!/bin/bash
cd /data
wget https://nginx.org/download/nginx-1.18.0.tar.gz &>/dev/null
if [ $? -eq 0 ];then
echo "nginx 下载成功"
else
echo "nginx 下载失败"
exit
fi
tar xf nginx-1.18.0.tar.gz
cd nginx-1.18.0
yum install pcre-devel zlib-devel gcc gcc-c++ make -y &>/dev/null
if [ $? -eq 0 ];then
echo "nginx 依赖环境安装成功"
else
echo "nginx 依赖环境安装失败请检查"
exit
fi
./configure --prefix=/apps/nginx
make -j2
make install
if [ $? -eq 0 ];then
echo "nginx 安装成功"
else
echo "nginx 安装失败"
exit
fi
echo "
[Unit]
Description=nginx - high performance web server
[Service]
Type=forking
PIDFile=/apps/nginx/logs/nginx.pid
ExecStart=/apps/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID
[Install]
WantedBy=multi-user.target
" > /usr/lib/systemd/system/nginx.service
systemctl start nginx
if [ $? -eq 0 ];then
echo "nginx 启动成功"
else
echo "nginx 启动失败"
fi
[root@localhost ~]# bash nginx.sh //执行脚本