shell编程100个常用技巧 (linuxshell编程怎么运行)

一、条件表达式

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编程实战》一书

shell编程判断三个数中最大数,shell编程从入门到实战免费送