1.1条件测试操作
Shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为0时表示成功,否则(非0值)表示失败或异常。使用专门的测试工具test命令,可对条件进行测试,并根据返回值来判断条件是否成立(返回值为0表示成立)。
test
命令使用语法:
test 条件表达式 [ 条件表达式 ] (符号两边至少要保证有一个空格)
[root@localhost ~]# test 1>5
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ 1>2 ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# test 8=8
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ 9=9 ]
[root@localhost ~]# echo $?
0
1.2 文件测试
语法:
[ 操作符 文件或者目录 ]
常用的操作符号:
-e :测试目录或文件是否存在(Exist)
-d:测试是否为目录(Directory)
-f:测试是否为文件(File)
-r:测试当前用户是否有权限读取(Read)
-w:测试当前用户是否有权限写入(Write)
-x:测试是否设置有可执行(Excute)权限,
-L:测试是否为符号连接
主意:要检查目录或者文件要用绝对路径去检查,
不使用绝对路径就会检查当前路径下的文件,
所以绝对经路径会更加的严谨。
扩展: [root@localhost ~]# [ -d /data ] && echo "yes" yes && 逻辑与。"而且"的意思
[root@localhost ~]# [ -e /data ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ -d /data ]
[root@localhost ~]# echo $?
0 //测试返回0,代表为真,是目录
[root@localhost ~]# [ -f /data ]
[root@localhost ~]# echo $?
1 //测试返回1,代表为假,不是文件
[root@localhost ~]# [ -r wang ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ -w wang ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ -x 2 ]
[root@localhost ~]# echo $?
1
整数值比较
语法: [ 整数变量1 操作符 整数变量2 ]
test 整数变量1 操作符号 整数变量2
常用的操作符:
-eq:等于 ==
-ne:不等于 !=
-gt:大于 \>
-lt:小于 \<
-le:小于等于
-ge:大于等于
[root@localhost ~]#a=1
[root@localhost ~]#b=2
[root@localhost ~]# test $a -eq 1
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ 2 -gt 1 ] && echo $?
0
扩充复杂使用:
[root@localhost ~]# [[ 99+1 -eq 100 ]]
[root@localhost ~]# echo $?
0
[root@localhost ~]# (( 99+1 == 100 ))
[root@localhost ~]# echo $?
0
&&符号表示:先执行前面的命令,执行成功以后再执行后面的命令
[root@localhost ~]# yum clean all && yum makecache
已加载插件:fastestmirror, langpacks
正在清理软件源: base extras updates
;号表示:如果前面的命令报错依旧会执行后面的命令
[root@localhost ~]# yum clean all ; yum makecache
已加载插件:fastestmirror, langpacks
/var/run/yum.pid 已被锁定,PID 为 48362 的另一个程序正在运行。
Another app is currently holding the yum lock; waiting for it to exit...
free 查看内存使用情况
[root@localhost ~]# free
total used free shared buff/cache available
Mem: 3865308 387016 2982040 9408 496252 3174792
Swap: 5242876 0 5242876
free -m 以兆为单位显示内存情况
[root@localhost ~]# free -m
total used free shared buff/cache available
Mem: 3774 373 2916 9 484 3104
Swap: 5119 0 5119
awk 可以截取字段值
[root@localhost ~]# free -m | grep 'Mem:' | awk '{print $4}'
2916
条件测试操作
字符串比较
格式1
[ 字符串1 = 字符串2 ]
[ 字符串1 ! = 字符串2 ]
格式2
[ -z "字符串" ] //检查字符串是否为空(Zero)。对于未定义或赋予空值的变量将视为空串
[ -n "字符串" ] //检查是否有字符串存在
主意:引号的使用,这是防止空格软乱代码的好方法
举例说明:
[ 字符串1 = 字符串2 ]
[root@localhost ~]# [ "$a" = "abc" ]
[root@localhost ~]# echo $?
1
[ 字符串1 ! = 字符串2 ]
[root@localhost ~]# [ "$a" != "abc" ]
[root@localhost ~]# echo $?
0
[ -z "字符串" ]
[root@localhost ~]# [ -z "$a" ]
[root@localhost ~]# echo $?
1
[ -n "字符串" ]
[root@localhost ~]# [ -n "$a" ]
[root@localhost ~]# echo $?
0
逻辑测试
格式1
[ 表达式1 ] 操作符 [ 表达式2 ]
格式2
命令1 操作符 命令2
常用的测试操作符
- -a或&&:逻辑与,"而且"的意思
- -o或||:逻辑或,"或者"的意思
- !:逻辑否
举例说明:
[ 表达式1 ] 操作符 [ 表达式2 ]
//前后两个表达式在而且的作用下,必须满足两边的要求才能让返回值为0,
[root@localhost ~]# [ $a -eq 6 ] && [ $a != 5 ]
[root@localhost ~]# echo $?
0
//在两个表达式只有一遍能满足条件的那么返回值为非0
[root@localhost ~]# [ $a -eq 6 -a $a == 2 ]
[root@localhost ~]# echo $?
1
命令1 操作符 命令2
两边的表达式只需要满足一个条件就能让返回值为0
[root@localhost ~]# [ $a -eq 6 -o $a == 2 ]
[root@localhost ~]# echo $?
0
[root@localhost ~]# [ $a -eq 6 ] || [ $a == 5 ]
[root@localhost ~]# echo $?
0
扩充:
三元运算符(C Java)
- 条件表达式?值1:值2
- 如果问号前面的表达式为真取冒号前面的值1
- 如果表达式为假就取冒号后面的值2
SHELL
[ 条件表达式 ] && 值1 || 值2
例子:
如果前面的条件成立就会执行或前面的运算符
[root@localhost ~]# [ 5 -gt 2 ] && echo true || echo false
true
如果条件不成立就会执行或后面的运算符
[root@localhost ~]# [ 5 -lt 2 ] && echo true || echo false
false
脚本测试机器是否在线
[root@localhost ~]# vim ping.sh
#!/bin/bash
#-c 几个包 -i间隔时间 -W 指定超时时间 -w(小写)代表多长时间停止ping
ping -c 3 -i 0.5 -w 2 $1 &> /dev/null && echo "$1 is online " || echo "$1 is offlib"
[root@localhost ~]# . ping.sh 192.168.85.20
192.168.85.20 is online
[root@localhost ~]# . ping.sh 192.168.85.30
192.168.85.30 is offlib
if语句的结构
单分支结构图:
执行逻辑:
- 成立:if语句会进行条件判断,当条件成立就会执行条件后面的代码块,当代码块执行完毕后就会结束if语句
- 不成立:if语句进行条件判断,如果不成立就直接结束if语句的判断
列子:
#!/bin/bash
if [ 3 -ge 2 ];then
echo "ok"
fi
[root@localhost ~]# . dome1.sh
ok
检查主机是否在线
#!/bin/bash
#-c 几个包 -i间隔时间 -W 指定超时时间 -w(小写)代表多长时间停止ping
#ping -c 3 -i 0.5 -w 2 $1 &> /dev/null && echo "$1 is online " || echo "$1 is offlib"
ping -c 3 -i 0.5 -w 2 $1 &> /dev/null
if [ $? -eq 0 ];then
echo "$1 is onlie"
fi
[root@localhost ~]# . ping.sh 192.168.85.20
192.168.85.20 is onlie
#!/bin/bash
if ping -c 3 -i 0.5 -w 2 $1 &> /dev/null
then
echo "$1 is online "
else
echo "$1 is offlib"
fi
[root@localhost ~]# . ping.sh 192.168.85.20
192.168.85.20 is online
[root@localhost ~]# . ping.sh 192.168.85.20
192.168.85.20 is offlib
判断磁盘空间使用率
#!/bin/bash
used_disk=$( df | grep /dev/sda1 |awk '{print $5}' |awk -F% '{print $1}')
if [ $used_disk -gt 2 ];then
echo "警告!!/ 目录磁盘空间不足,目前磁盘使用率为${used_disk}%"
fi
[root@localhost ~]# . demo.sh
警告!!/ 目录磁盘空间不足,目前磁盘使用率为5%
三种查看端口号的方法
netstat -nltp | grep httpd
ss -nltp | grep httpd
lsof -i :80
#!/bin/bash
#80端口是否在监听
ss -nltp | grep httpd &> /dev/null
if [ $? -eq 0 ];then
echo "httpd网站服务已在运行中"
else
echo "httpd网站服务未运行,正在启动httpd服务........"
systemctl start httpd
if ss -nltp | grep httpd &> /dev/null
then
echo "httpd网站服务启动成功!!"
else
echo "httpd网站服务启动失败!!"
fi
fi
[root@localhost ~]# . demo3.sh
httpd网站服务未运行,正在启动httpd服务........
httpd网站服务启动成功!!
[root@localhost ~]# . demo3.sh
httpd网站服务已在运行中
多分支结构
多分支依据的执行效率不高,因为它是一层一层的判断
- 首先判断if语句里面的条件测试操作,如果if条件测试操作满足条件就会执行then里面的代码块
- 如果if语句不满足条件,则会进一步判断接下来的eilf条件测试操作是否满足条件,满足条件就会走then的代码块,如果不满足,就会走else条件的代码块
例子:
考试分数
#!/bin/bash
read -p "请输入你的分数(0-100);" num
if [ $num -eq 100 ];then
echo "你真棒!"
elif [ $num -ge 90 ] && [ $num -le 99 ];then
echo "错题抄写10遍!"
elif [ $num -ge 70 -a $num -lt 90 ];then
echo "错题抄写20遍! "
elif [[ $num -gt 59 && $num -le 69 ]];then
echo "错题抄写30遍!"
elif [ $num -lt 60 ];then
echo "所有题目抄写30遍! "
else
echo "输入有误,请输入 0~100 的范围! "
fi
[root@localhost ~]# . demo4.sh
请输入你的分数(0-100);120
输入有误,请输入 0~100 的范围!
[root@localhost ~]# . demo4.sh
请输入你的分数(0-100);100
你真棒!
[root@localhost ~]# . demo4.sh
请输入你的分数(0-100);80
错题抄写20遍!
case语句结构
并行判断。同时判断,执行效率高一些
如果传入的值满足模式1的值,那么就会去执行模式一所对应的代码块
如果不满足条件会判断模式二,满足模式二的条件就会走模式二的代码块
如果都不满足就会直接结束
列子:
考试分数
#!/bin/bash
read -p "请输入你的分数(0-100);" num
case $num in
100)
echo "你真棒!"
;;
9[0-9])
echo "错题抄写10遍!"
;;
[78][0-9])
echo "错题抄写20遍! "
;;
6[0-9])
echo "错题抄写30遍!"
;;
[0-9]|[1-5][0-9] )
echo "所有题目抄写30遍! "
;;
*)
echo "输入有误,请输入 0~100 的范围! "
;;
esac
请输入你的分数(0-100);120
输入有误,请输入 0~100 的范围!
[root@localhost ~]# . demo5.sh
请输入你的分数(0-100);20
所有题目抄写30遍!
[root@localhost ~]# . demo5.sh
请输入你的分数(0-100);90
错题抄写10遍!
[root@localhost ~]# . demo5.sh
请输入你的分数(0-100);2
所有题目抄写30遍!
#!/bin/bash
read -p "请输入你的分数(0-100);" num
[ $num -eq 100 ] && a='A'
[ $num -ge 90 -a $num -le 99 ] && a='B'
[ $num -ge 70 -a $num -le 89 ] && a='C'
[ $num -ge 60 -a $num -le 69 ] && a='D'
[ $num -ge 0 -a $num -le 59 ] && a='E'
case $a in
A)
echo "你真棒!"
;;
B)
echo "错题抄写10遍!"
;;
C)
echo "错题抄写20遍! "
;;
D)
echo "错题抄写30遍!"
;;
E)
echo "所有题目抄写30遍! "
;;
*)
echo "输入有误,请输入 0~100 的范围! "
;;
esac
[root@localhost ~]# . demo6.sh
请输入你的分数(0-100);100
你真棒!
[root@localhost ~]# . demo6.sh
请输入你的分数(0-100);5
所有题目抄写30遍!
chkconfig --add添加/etc/init.d/目录中的脚本后,使用 service 命令来进行的管理操作就相当于使用路径指定脚本文件执行操作
[root@localhost init.d]# vim firewalld
#!/bin/bash
#chkconfig -99 10
case $1 in
start)
systemctl start firewalld.service
;;
stop)
systemctl stop firewalld.service
;;
restart)
$0 stop
$0 start
;;
status)
systemctl status firewalld.service
;;
*)
echo "usage: $0 {start|stop|restart|status}"
esac
[root@localhost init.d]# chkconfig --add firewalld
[root@localhost init.d]# service firewalld start