一、条件表达式
1.1 文件判断
常用文件测试操作符
常用文件测试操作符说明-d文件,d的全拼为directory文件存在且为目录则为真,即测试表达式成立-f文件,f的全拼为file文件存在且为普通文件则为真,即测试表达式成立-e文件,e的全拼为exist文件存在则为真,即测试表达式成立。注意区别于“-f”,-e不辨别是目录还是文件-r文件,r的全拼为read文件存在且可读则为真,即测试表达式成立-s文件,s的全拼为size文件存在且文件大小不为0则为真,即测试表达式成立-w文件,w的全拼为write文件存在且可写则为真,即测试表达式成立-x文件,x的全拼为executable文件存在且可执行则为真,即测试表达式成立-L文件,L的全拼为link文件存在且为链接文件则为真,即测试表达式成立fl -nt f2,nt 的全拼为 newer than文件fl比文件f2新则为真,即测试表达式成立。根据文件的修改时间来计算fl -ot f2,ot 的全拼为 older than文件fl比文件f2旧则为真,即测试表达式成立。根据文件的修改时间来计算
判断文件是否存在
[root@oldboy scripts]# [ -f /etc/hosts ] [root@oldboy scripts]# echo $? 0 [root@oldboy scripts]# [ -f /etc/hosts1 ] [root@oldboy scripts]# echo $? 1
判断文件是否存在,返回方式
[root@oldboy scripts]# [ -f /etc/hosts ] && echo "文件存在" || echo "文件不存在" 文件存在 [root@oldboy scripts]# [ -f /etc/hosts1 ] && echo "文件存在" || echo "文件不存在" 文件不存在
判断目录是否存在
[root@oldboy scripts]# [ -d /tmp ] && echo "目录存在" || echo "目录不存在" 目录存在 [root@oldboy scripts]# [ -d /tmp1 ] && echo "目录存在" || echo "目录不存在" 目录不存在
使用变量的方法进行判断
dir=/etc1/;[ -d $dir ] && tar zcf etc.tar.gz $dir || echo "$dir目录不存在"
1.2 字符串判断
字符串测试操作符
常用字符串测试操作符说明-n "字符串"若字符串的长度不为0,则为真,即测试表达式成立,n可以理解为no zero-Z "字符串"若字符串的长度为0,则为真,即测试表达式成立,z可以理解为zero的缩写"串 1"== "串 2"若字符串1等于字符串2,则为真,即测试表达式成立,可使用"=="代替"=""串 1" != "串 2"若字符串1不等于字符串2,则为真,即测试表达式成立,但不能用"!=="代替"!="1.对于字符串的测试,一定要将字符串加双引号之后再进行比较。2.空格非空
-z 判断字符串长度
[root@oldboy scripts]# x= ; [ -z "$x" ] && echo "输入为空" || echo ’输入有内容’ 输入为空 [root@oldboy scripts]# x=12 ; [ -z "$x" ] && echo "输入为空" || echo ’输入有内容’ 输入有内容
-n 判断字符串长度
[root@oldboy scripts]# x=12 ; [ -n "$x" ] && echo "输入有内容" || echo ’输入为空’ 输入有内容 [root@oldboy scripts]# x= ; [ -n "$x" ] && echo "输入有内容" || echo ’输入为空’ 输入为空
"串 1" == " 串 2 " 使用定义变量的方式进行判断
cmd=$1 [ "$cmd" == "start" ] && echo start # 测试 [root@oldboy scripts]# cmd=start;[ "$cmd" == "start" ] && echo start start
1.3 整数判断
整数二元比较操作符参考
在[]以及test中在(())和[[]]中说明使用的比较符号使用的比较符号-eq==或=相等,全拼为equal-ne!=不相等,全拼为not equal-gt>大于,全拼为greater than-ge>=大于等于,全拼为greater equal-lt<小于,全拼为丨ess than-le<=小于等于,全拼为less equal
判断两数是否相等
[root@oldboy scripts]# [ 1 -eq 1 ] [root@oldboy scripts]# echo $? 0 [root@oldboy scripts]# [ 1 -eq 2 ] [root@oldboy scripts]# echo $? 1
大于等于
[root@oldboy ~]# [ 11 -ge 1 ] && echo "成立" || echo "不成立" 成立
小于
[root@oldboy ~]# [ 11 -lt 1 ] && echo "成立" || echo "不成立" 不成立
大于
[root@oldboy ~]# [ 11 -gt 1 ] && echo "成立" || echo "不成立" 成立
不等于
[root@oldboy ~]# [ 11 -ne 1 ] && echo "成立" || echo "不成立" 成立
1.4 逻辑符号
常用逻辑操作符
在[]和test中使用的操作符说明在[[]]和中使用的操作符说明-a[ 条件A -a 条件B ]&&and,与,两端都为真,则结果为真A与B都要成立,整个表达式才成立-o[ 条件A -o 条件B]||or,或,两端有一个为真,则结果为真A与B都不成立,整个表达式才不成立!
!not,非,两端相反,则结果为真
逻辑操作符与整数判断配合
[root@oldboy ~]# [ 11 -ne 1 ] && echo "成立" || echo "不成立" 成立
取反
[root@oldboy ~]# [ ! 11 -ne 1 ] && echo "成立" || echo "不成立" 不成立
两边都为真
[root@oldboy ~]# [ 11 -ne 1 -a 1 -eq 1 ] && echo "成立" || echo "不成立" 成立
至少有一边为真
[root@oldboy ~]# [ 11 -ne 1 -o 1 -eq 1 ] && echo "成立" || echo "不成立" 成立
感叹号的特殊用法
[root@oldboy ~]# !516 ls anaconda-ks.cfg bootime.avg setup.sh vim
二、if条件语句
# 条件表达式和if语句可以互相转换
2.1 三种语法
单分支语句
if [ -f /etc/hosts ] then echo ’文件存在’ fi
双分支语句
if [ -f /etc/hosts ] then echo "文件存在" else echo "文件不存在" echo "..." >>/tmp/test.log fii
多分支语句
if [ -f /etc/hosts ] then echo " hosts文件存在" elif [ -f /etc/host ] then echo " host文件存在" fi
2.2 if条件语句小结
单分支:一个条件一个结果
双分支:一个条件两个结果
多分支:多个条件多个结果
三、case条件结构语句
3.1 case语法结构
case "字符串变量" in 值1) 指令1 ;; 值2) 指令2 ;; 值*) 指令 esac
3.2 case与if的对比
case书写方式
case $name in 值1) 指令1 ;; 值2) 指令2 ;; *) 指令 esac
if书写方式
if [ $name == "值1" ] then 指令1 elif [ $name == "值2" ] then 指令2 else 指令 fi
3.3 case值的书写方式
apple) echo -e "$RED_COLOR apple $RES" ;;
也可以这样写,输入2种格式找同一个选项
apple|APPLE) echo -e "$RED_COLOR apple $RES" ;;
3.4 case语句小结
case语句就相当于多分支的if语句。case语句的优势是更规范、易读。
case语句适合变量的值少,且为固定的数字或字符串集合。(1,2,3)或(start,stop,restart)。
系统服务启动脚本传参的判断多用case语句,多参考rpcbind/nfs/crond脚本;菜单脚本也可以使用case。
3.5 写脚本规范及注意事项
1.变量名称不能和系统已经存在的命令等重复 free == > Free
2. 判断单位要统一
3. 脚本一行不超过一屏的一半。
4. 能写成变量的内容尽量写成变量
四、练习题
4.1 【练习题1】监控Memcached缓存服务是否正常
监控Memcached缓存服务是否正常,模拟用户(web客户端)检测。
使用nc命令加上set/get来模拟检测。
脚本内容:
1 [root@oldboy scripts]# vim memcache_check.sh 2 #!/bin/bash 3 ############################################################# 4 # File Name: memcache_check.sh 5 # Version: V1.0 6 # Author: oldboy 7 # Organization: http://blog.oldboyedu.com 8 # Created Time : 2026-03-15T18:48:16+00:00 9 # Description: 10 ############################################################# 11 . /etc/init.d/functions 12 . /etc/init.d/run # 函数 jingdutiao 使用 13 MemPort=`netstat -lntp |grep -c 0.0.0.0:11211` 14 Set_Key=’printf "set oldboy2017 0 10 8\r\noldboy2018\r\n"|nc 10.0.0.180 11211’ 15 Get_Key=’printf "get oldboy2017\r\n" |nc 10.0.0.180 11211 |grep -c oldboy2018’ 16 ReStart=’systemctl restart memcached.service’ 17 18 if [ $MemPort -eq 1 ] 19 then 20 $Set_Key 21 $Get_Key 22 if [ $? -ne 1 ] 23 then 24 action "Memcached 运行正常!" /bin/true 25 else 26 action "Memcached 服务异常!" /bin/false 27 fi 28 else 29 action "服务未启动!" /bin/false 30 $ReStart 31 jingdutiao 32 fi
4.2 【练习题2】使用(case)编写rsync管理脚本
写网络服务独立进程模式下Rsync的系统启动脚本,例如:/etc/init.d/rsyncd {start|stop|restart}。
要求:
1.要使用系统函数库技巧。
2.要用函数,不能一坨的方式。
3.在centos 6中 可被chkconfig管理。
注意:
服务的停止操作和启动操作之间要有间隔时间,使用sleep 1
pkill 进程 sleep 1 start 服务
rsync服务启动脚本
1 [root@oldboy scripts]# cat rsyncd
2 #!/bin/bash
3 #############################################################
4 # File Name: rsync_admin.sh
5 # Version: V1.0
6 # Author: oldboy
7 # Organization: http://blog.oldboyedu.com
8 # Created Time : 2026-03-15T18:48:16+00:00
9 # Description:
10 #############################################################
11
12 . /etc/init.d/functions
13 . /etc/init.d/run
14
15 Rsync_Port=`netstat -lntup |grep -c 0.0.0.0:873`
16 Rsync_COM1=’rsync --daemon’
17 Rsync_COM2=’pkill rsync’
18
19 Rsync_Start() {
20 Rsync_Port1=`netstat -lntup |grep -c 0.0.0.0:873`
21 if [ $Rsync_Port1 -ne 0 ]
22 then
23 action "服务已启动" /bin/false
24 exit 3
25 else
26 $Rsync_COM1
27 #action "Rsync 启动" /bin/true
28 QiDong
29 fi
30 }
31
32 Rsync_Stop() {
33 Rsync_Port2=`netstat -lntup |grep -c 0.0.0.0:873`
34 if [ $Rsync_Port2 -eq 0 ]
35 then
36 action "服务未启动" /bin/false
37 exit 3
38 else
39 $Rsync_COM2
40 #action "Rsync 停止" /bin/true
41 TingZhi
42 fi
43 }
44
45 Rsync_Status() {
46 if [ $Rsync_Port -eq 1 ]
47 then
48 echo "Rsync 服务运行中..."
49 else
50 echo "Rsync 服务未运行"
51 fi
52 }
53
54 Rsync_Restart() {
55 Rsync_Stop
56 Rsync_Start
57 }
58 COMMAND=$1
59
60 case "$COMMAND" in
61 start)
62 Rsync_Start
63 ;;
64 stop)
65 Rsync_Stop
66 ;;
67 status)
68 Rsync_Status
69 ;;
70 restart|reload|force-reload)
71 Rsync_Restart
72 ;;
73 *)
74 echo $"Usage: $0 {start|stop|status|restart|reload|force-reload}"
75 exit 2
76 esac
4.3 【练习题3】菜单自动化软件部署脚本实践
综合实例:打印选择菜单,按照选择一键安装不同的Web服务。
示例菜单:
[root@oldboy scripts]# sh menu.sh
1.[install lamp]
2.[install lnmp]
3.[exit]
pls input the num you want:
要求:
1、当用户输入1时,输出“start installing lamp.提示”然后执行/server/scripts/lamp.sh,脚本内容输出"lampis installed"后退出脚本,工作中就是正式lamp一键安装脚本;
echo ’echo lampis installed’ > /server/scripts/lamp.sh chmod +x /server/scripts/lamp.sh
2、当用户输入2时,输出“start installing lnmp.提示” 然后执行/server/scripts/lnmp.sh输出"lnmpis installed"后退出脚本,工作中就是正式lnmp一键安装脚本;
echo ’echo lnmpis installed’ > /server/scripts/lnmp.sh chmod +x /server/scripts/lnmp.sh
3、当输入3时,退出当前菜单及脚本;
4、当输入任何其它字符,给出提示“Input error”后退出脚本;
5、要对执行的脚本进行相关的条件判断,例如:脚本文件是否存在,是否可执行等判断。
脚本 内容
1 [root@oldboy scripts]# cat menu.sh 2 #!/bin/bash 3 ############################################################# 4 # File Name: menu.sh 5 # Version: V1.0 6 # Author: oldboy 7 # Organization: http://blog.oldboyedu.com 8 # Created Time : 2026-03-15T18:48:16+00:00 9 # Description: 10 ############################################################# 11 12 cat <<EOF 13 1.[install lamp] 14 2.[install lnmp] 15 3.[exit] 16 EOF 17 18 read -p "please input the num you want:" Num 19 20 case "$Num" in 21 1) 22 if [ -f /server/scripts/lamp.sh ] 23 then 24 echo -e "\033[36mstart installing lamp\033[0m" 25 /server/scripts/lamp.sh 26 else 27 echo -e "\033[5;41;37m /server/scripts/lamp.sh 文件不存在 \033[0m" 28 fi 29 ;; 30 2) 31 if [ -f /server/scripts/lnmp.sh ] 32 then 33 echo -e "\033[36mstart installing lnmp\033[0m" 34 /server/scripts/lnmp.sh 35 else 36 echo -e "\033[5;41;37m /server/scripts/lnmp.sh 文件不存在 \033[0m" 37 fi 38 ;; 39 3) 40 exit 41 ;; 42 *) 43 echo -e "\033[31mInput error \033[0m" 44 exit 2 45 esac
4.4 if 与 case 对比
if 语句类似黑名单,需要把这种错误场景封堵
case 语句类似白名单,只要把正确结果列完整即可
本文内容来自 老男孩Linux云计算运维优秀学员课后笔记整理,《跟老男孩学习Linux运维:Shell编程实战》一书
