Shell编程基础篇-下

1.1 条件表达式

1.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 f2nt 的全拼为 newer than

文件fl比文件f2新则为真,即测试表达式成立。根据文件的修改时间来计算

fl -ot f2ot 的全拼为 older than

文件fl比文件f2旧则为真,即测试表达式成立。根据文件的修改时间来计算

判断文件是否存在

[root@clsn scripts]# [ -f /etc/hosts ]
[root@clsn scripts]# echo $?
0
[root@clsn scripts]# [ -f /etc/hosts1 ]
[root@clsn scripts]# echo $?
1

判断文件是否存在,返回方式

[root@clsn scripts]# [ -f /etc/hosts ] && echo "文件存在" || echo "文件不存在" 
文件存在
[root@clsn scripts]# [ -f /etc/hosts1 ] && echo "文件存在" || echo "文件不存在" 
文件不存在

判断目录是否存在

[root@clsn scripts]# [ -d /tmp ] && echo "目录存在" || echo "目录不存在" 
目录存在
[root@clsn scripts]# [ -d /tmp1 ] && echo "目录存在" || echo "目录不存在" 
目录不存在

使用变量的方法进行判断

dir=/etc1/;[ -d $dir ] && tar zcf etc.tar.gz $dir || echo "$dir目录不存在"

1.1.2 字符串判断

字符串测试操作符 

常用字符串测试操作符

说明

-n "字符串"

若字符串的长度不为0,则为真,即测试表达式成立,n可以理解为no zero

-Z "字符串"

若字符串的长度为0,则为真,即测试表达式成立,z可以理解为zero的缩写

" 1"== " 2"

若字符串1等于字符串2,则为真,即测试表达式成立,可使用"=="代替"="

" 1" = " 2"        

若字符串1不等于字符串2,则为真,即测试表达式成立,但不能用"!=="代替"!="

1.对于字符串的测试,一定要将字符串加双引号之后再进行比较。

2.空格非空

-z 判断字符串长度

[root@clsn scripts]# x=  ; [ -z "$x" ] && echo "输入为空" || echo '输入有内容'
输入为空
[root@clsn scripts]# x=12 ; [ -z "$x" ] && echo "输入为空" || echo '输入有内容'
输入有内容

-n 判断字符串长度

[root@clsn scripts]# x=12 ; [ -n "$x" ] && echo "输入有内容" || echo '输入为空'
输入有内容
[root@clsn scripts]# x= ; [ -n "$x" ] && echo "输入有内容" || echo '输入为空'
输入为空

"串 1" == " 串 2 "       使用定义变量的方式进行判断

cmd=$1
[ "$cmd" == "start" ] && echo start
# 测试
[root@clsn scripts]# cmd=start;[ "$cmd" == "start" ] && echo start
start

1.1.3 整数判断

整数二元比较操作符参考

[]以及test

使用的比较符号

(())[[]]

使用的比较符号

说明

-eq

===

相等,全拼为equal

-ne

=

不相等,全拼为not equal

-gt

大于,全拼为greater than

-ge

>=

大于等于,全拼为greater equal

-lt

小于,全拼为丨ess than

-le

<=

小于等于,全拼为less equal

判断两数是否相等

[root@clsn scripts]# [ 1 -eq 1 ]
[root@clsn scripts]# echo $?
0
[root@clsn scripts]# [ 1 -eq 2 ]
[root@clsn scripts]# echo $?
1

大于等于

[root@clsn ~]# [ 11 -ge 1 ] && echo "成立" || echo "不成立"
成立

小于

[root@clsn ~]# [ 11 -lt 1 ] && echo "成立" || echo "不成立"
不成立

大于

[root@clsn ~]# [ 11 -gt 1 ] && echo "成立" || echo "不成立"
成立

不等于

[root@clsn ~]# [ 11 -ne 1 ] && echo "成立" || echo "不成立"
成立

1.1.4 逻辑符号

常用逻辑操作符 

[]test中使用的操作符

说明

[[]]和中使用的操作符

说明

-a

[ 条件A -a  条件B ]

AB都要成立,整个表达式才成立

&&

and,与,两端都为真,则结果为真

-o

[ 条件A -o  条件B]

AB都不成立,整个表达式才不成立

||

or,或,两端有一个为真,则结果为真

 

!

not,非,两端相反,则结果为真

逻辑操作符与整数判断配合

[root@clsn ~]# [ 11 -ne 1 ] && echo "成立" || echo "不成立"
成立

 取反

[root@clsn ~]# [ ! 11 -ne 1 ] && echo "成立" || echo "不成立"
不成立

两边都为真

[root@clsn ~]# [  11 -ne 1 -a 1 -eq 1 ] && echo "成立" || echo "不成立"
成立

至少有一边为真

[root@clsn ~]# [  11 -ne 1 -o 1 -eq 1 ] && echo "成立" || echo "不成立"
成立

感叹号的特殊用法

         使用历史命令,感叹号加上history中的序号,即可执行

[root@clsn ~]#  !516
 ls
anaconda-ks.cfg  bootime.avg  setup.sh  vim

1.1.5 【练习题】开发3个shell脚本比较2个整数大小

要求:

1. 分别以定义变量,脚本传参以及read读入的方式写3个脚本。

2. 用条件表达式(禁止if语句)进行判断。

3. 2个整数的比较结果输出到屏幕,出错需要提示。

使用定义变量方法

复制代码
[root@clsn panduan1]# cat panduan1.sh 
#!/bin/bash
#############################################################
# File Name: panduan1.sh
# Version: V1.0
# Author: clsn
# Organization: http://blog.znix.top
# Created Time : 2017-12-06 11:27:32
# Description:
#############################################################

NUM1=6
NUM2=2

expr 1 + $NUM1  &>/dev/null
[ $? -eq 2 ] && echo "$NUM1 不是整数 " &&  exit 2
expr 1 + $NUM2 &>/dev/null
[ $? -eq 2 ] && echo "$NUM2 不是整数 " &&  exit 2

[ "$NUM1" -eq "$NUM2" ] && echo $NUM1 = $NUM2  && exit
[ "$NUM1" -gt "$NUM2" ] && echo $NUM1 \> $NUM2 && exit
[ "$NUM1" -lt "$NUM2" ] && echo $NUM1 \< $NUM2
复制代码

使用传参方法

复制代码
[root@clsn panduan1]# cat panduan_chuanchan.sh 
#!/bin/bash
#############################################################
# File Name: panduan1.sh
# Version: V1.0
# Author: clsn
# Organization: http://blog.znix.top
# Created Time : 2017-12-06 11:27:32
# Description:
#############################################################
[ $# -ne 2 ] && echo "UASGE $0 num1 num2 " && exit

NUM1=$1
NUM2=$2

expr 1 + $NUM1  &>/dev/null
[ $? -eq 2 ] && echo "$NUM1 不是整数 " &&  exit 2
expr 1 + $NUM2  &>/dev/null
[ $? -eq 2 ] && echo "$NUM2 不是整数 " &&  exit 2

[ "$NUM1" -eq "$NUM2" ] && echo $NUM1 = $NUM2  && exit
[ "$NUM1" -gt "$NUM2" ] && echo $NUM1 \> $NUM2 && exit
[ "$NUM1" -lt "$NUM2" ] && echo $NUM1 \< $NUM2
复制代码

使用read读入

复制代码
[root@clsn panduan1]# cat panduan_read.sh 
#!/bin/bash
#############################################################
# File Name: panduan1.sh
# Version: V1.0
# Author: clsn
# Organization: http://blog.znix.top
# Created Time : 2017-12-06 11:27:32
# Description:
#############################################################

read -p "请输入第一个整数:" NUM1
read -p "请输入第二个整数:" NUM2

expr 1 + $NUM1  &>/dev/null
[ $? -eq 2 ] && echo "$NUM1 不是整数 " &&  exit 2
expr 1 + $NUM2  &>/dev/null 
[ $? -eq 2 ] && echo "$NUM2 不是整数 " &&  exit 2

[ "$NUM1" -eq "$NUM2" ] && echo "$NUM1 = $NUM2"  && exit
[ "$NUM1" -gt "$NUM2" ] && echo "$NUM1 > $NUM2" && exit
echo "$NUM1 < $NUM2"
复制代码

1.2 if条件语句

  # 条件表达式和if语句可以互相转换

1.2.1 三种语法

单分支语句

if [ -f /etc/hosts ]

then

    echo '文件存在'

fi

双分支语句

复制代码
if [ -f /etc/hosts ]  

then

   echo "文件存在"

else

echo "文件不存在"

   echo "..." >>/tmp/test.log

fi
复制代码

多分支语句

复制代码
if [ -f /etc/hosts ]  

then

   echo " hosts文件存在"

elif [ -f /etc/host ]

then

   echo " host文件存在"

fi
复制代码

1.2.2 if条件语句小结

  单分支:一个条件一个结果

  双分支:一个条件两个结果

  多分支:多个条件多个结果

1.2.3 【练习题1】输入2个数字,比较大小(使用if语句结合条件表达式实现) 

说明:

3个脚本:使用直接赋值,传参,read任一种方法写3种脚本(单分支,双分支,多分支)

示例脚本一:

复制代码
 1 [root@clsn panduan1]# cat if_panduan_1.sh 
 2 #!/bin/bash
 3 #############################################################
 4 # File Name: panduan1.sh
 5 # Version: V1.0
 6 # Author: clsn
 7 # Organization: http://blog.znix.top
 8 # Created Time : 2017-12-06 11:27:32
 9 # Description:
10 #############################################################
11 
12 read -p "请输入第一个整数:" NUM1
13 expr 1 + $NUM1  &>/dev/null
14     if [ $? -eq 2 ] 
15       then
16         echo "$NUM1 不是整数 "
17         exit 2
18     fi
19 
20 read -p "请输入第二个整数:" NUM2
21 expr 1 + $NUM2  &>/dev/null 
22     if [ $? -eq 2 ] 
23       then 
24          echo "$NUM2 不是整数 " 
25          exit 2
26     fi
27 
28 # 判断输入数值大小 
29     if [ $NUM1 -eq $NUM2 ]
30       then
31         echo "$NUM1 = $NUM2"
32         exit
33     fi
34   
35     if [ $NUM1 -gt $NUM2 ] 
36       then 
37         echo "$NUM1 > $NUM2" 
38         exit
39     fi
40    
41     if [ $NUM1 -lt $NUM2 ]
42       then
43         echo "$NUM1 < $NUM2"
44     fi
View Code read方法 单分支
复制代码

示例脚本二:

复制代码
 1 [root@clsn panduan1]# cat if_panduan_2.sh 
 2 #!/bin/bash
 3 #############################################################
 4 # File Name: if_panduan_2.sh
 5 # Version: V1.0
 6 # Author: clsn
 7 # Organization: http://blog.znix.top
 8 # Created Time : 2017-12-06 11:27:32
 9 # Description:
10 #############################################################
11 
12 read -p "请输入第一个整数:" NUM1
13   expr 1 + $NUM1  &>/dev/null
14       if [ $? -eq 2 ] 
15         then
16           echo "$NUM1 不是整数 "
17           exit 2
18       fi
19 
20 read -p "请输入第二个整数:" NUM2
21   expr 1 + $NUM2  &>/dev/null 
22       if [ $? -eq 2 ] 
23         then 
24            echo "$NUM2 不是整数 " 
25            exit 2
26       fi
27 
28 # 判断输入数值大小 
29     if [ $NUM1 -eq $NUM2 ]
30       then
31         echo "$NUM1 = $NUM2"
32         exit
33     else
34         if [ $NUM1 -gt $NUM2 ]
35           then
36             echo "$NUM1 > $NUM2" 
37             exit
38         else
39             if [ $NUM1 -lt $NUM2 ]
40               then
41               echo "$NUM1 < $NUM2"
42             fi
43         fi
44     fi
View Code 双分支
复制代码

示例脚本三:

复制代码
 1 [root@clsn panduan1]# cat if_panduan_3.sh 
 2 #!/bin/bash
 3 #############################################################
 4 # File Name: if_panduan_3.sh
 5 # Version: V1.0
 6 # Author: clsn
 7 # Organization: http://blog.znix.top
 8 # Created Time : 2017-12-06 11:27:32
 9 # Description:
10 #############################################################
11 
12 read -p "请输入第一个整数:" NUM1
13   expr 1 + $NUM1  &>/dev/null
14    NUM1_FH=$?   
15       if [ $NUM1_FH -eq 2 ] 
16         then
17           echo "$NUM1 不是整数 "
18           exit 2
19       else  
20         read -p "请输入第二个整数:" NUM2
21         expr 1 + $NUM2  &>/dev/null 
22         NUM2_FH=$?
23         if [ $NUM2_FH -eq 2 ] 
24          then 
25            echo "$NUM2 不是整数 " 
26            exit 2
27         fi
28       fi
29 
30 # 判断输入数值大小 
31     if [ $NUM1 -eq $NUM2 ]
32       then
33         echo "$NUM1 = $NUM2"
34         exit
35     elif [ $NUM1 -gt $NUM2 ]
36       then
37         echo "$NUM1 > $NUM2" 
38         exit
39     elif [ $NUM1 -lt $NUM2 ]
40       then
41         echo "$NUM1 < $NUM2"
42     fi
View Code 多分支
复制代码

1.2.4 【练习题2】系统内存低于100M邮件报警,加入计划任务,3分钟检查一次。

对于开发程序而言,一般来说应该遵循下面的3步法则。

1)分析需求

    明白开发需求,是完成程序的大前提,因此,分析需求至关重要,一切不以需求为主的程序开发,都是耍流氓的!

2)设计思路

设计思路就是根据需求,把需求进行拆解,分模块逐步实现,例如本题可以分为如下几步:

1)获取当前系统剩余内存的值(先在命令行实现)。

2)配置邮件报警(可采用第三方邮件服务器)。

3)判断取到的值是否小于100MB,如果小于100MB,就报警(采用if语句)。

4)编码实现Shell脚本。

5)加入crond定时任务,每三分钟检查一次。

3)编码实现

    编码实现就是具体的编码及调试过程,工作中很可能需要先在测试环境下调试,调试好了,再发布到生产环境中。

第一步 先配置邮件服务,保证能够发生邮件

echo 'set from=mail@znix.top smtp=smtp.znix.top smtp-auth-user=mail@znix.top  smtp-auth-password=****** smtp-auth=login' >> /etc/mail.rc
发送测试邮件发送
echo "`date +%F_%T`" |mail -s "这是测试邮件" admin@znix.top

 

第二步编写检查脚本

复制代码
[root@clsn scripts]# cat mem_info.sh 
#!/bin/bash
##############################################################
# File Name: mem_info.sh
# Version: V1.0
# Author: clsn
# Organization: http://blog.znix.top
# Created Time : 2017-12-06 8:42:50
# Description:
##############################################################

Mem=`free -m |awk 'NR==2{print $NF}'`
host=`hostname`
Ip=`hostname -I`
Date=`date +%F_%T`
mail_file=/tmp/mail.s
dest_user=admin@znix.top

if [ $Mem -lt 100 ]
then
   echo "发生时间: $Date" >$mail_file
   echo "发生主机: $host  主机IP地址: $Ip " >> $mail_file
   echo "内存余量: $Mem M" >> $mail_file
   mail -s "【警告】内存不足了呀!"  $dest_user < $mail_file
fi
复制代码

第三步测试脚本(可以修改判断的值)

[root@clsn scripts]# sh mem_info.sh

 

第四步 脚本测试成功,写入定时任务

[root@clsn panduan1]# crontab -l 
# 检查内存剩余大小
*/3 * * * * /bin/sh /server/scripts/panduan/mem_info.sh  &>/dev/null

至此,一个监控脚本就写好了

1.2.5 【练习题3】模拟编写启动nginx脚本

脚本内容

复制代码
 1 [root@clsn scripts]# cat nginx.sh 
 2 #!/bin/bash
 3 ##############################################################
 4 # File Name: nginx.sh
 5 # Version: V1.0
 6 # Author: clsn
 7 # Organization: http://blog.znix.top
 8 # Created Time : 2017-12-05 20:56:06
 9 # Description:
10 ##############################################################
11 . /etc/init.d/functions  
12 
13 StartCheck=`netstat -lntup  |grep -c 80`
14 StartCMD='/application/nginx/sbin/nginx '
15 StopCMD='/application/nginx/sbin/nginx -s stop '
16 StatusCheck=`netstat -lntp|grep -c nginx`
17 ReloadCMD='/application/nginx/sbin/nginx -s reload'
18 CheckCMD='/application/nginx/sbin/nginx  -t'
19 UsaGe="Usage: $0 {start|stop|status|reload|check}"
20 
21 
22 COMMAND=$1
23 
24 if [  $# -ne 1 ]
25   then
26     echo $UsaGe  && exit 2
27 fi 
28 
29 if [ $COMMAND = start ]
30  then
31     if [ $StartCheck  == 1  ]
32       then
33       action  "启动Nginx失败,端口被占用"  /bin/false
34     else
35       $StartCMD
36       action  "启动Nginx"  /bin/true
37     fi
38 elif [ $COMMAND = stop ]
39   then
40       $StopCMD  &>/dev/null
41       if [ $? -eq 0 ]
42         then
43           action   "停止Nginx"   /bin/true 
44       else
45           action   "停止Nginx"   /bin/false
46       fi
47 elif [ $COMMAND = status ]
48   then
49     if [ $StatusCheck -eq 1 ]
50       then
51         echo "nginx 正在运行..."
52     else
53         echo "Nginx 未运行."
54     fi
55 elif [ $COMMAND = reload ]
56   then
57     $ReloadCMD
58     action  "reload" /bin/true
59 elif [ $COMMAND = check ]
60   then 
61     $CheckCMD
62 else 
63  echo $UsaGe
64  exit 2
65 fi
View Code nginx 启动脚本
复制代码

脚本执行过程: 

1.2.6 【练习题5】Web及MySQL服务异常监测案例

用if条件语句实现对Nginx Web服务以及MySQL数据库服务是否正常进行检测,如果服务未启动,则启动相应服务。

脚本编写思路:

判断web服务器正常 ↓

  1、进程 ps -ef |grep [n]ginx
  2、端口  netstat  ss losf telnet  nc  nmap 
  3、curl 页面 返回值
  4、curl check.html 的内容

判断mysql服务器正常 ↓

    1、端口 netstat  ss losf telnet  nc  nmap
    2、进程 ps -ef |grep [m]ysql
    3、mysql 登录访问看一下
    4、mysql insert一个数据 select一个数据

web服务监控脚本示例

复制代码
 1 [root@clsn scripts]# cat  web_check.sh 
 2 #!/bin/bash
 3 #############################################################
 4 # File Name: web_check.sh
 5 # Version: V1.0
 6 # Author: clsn
 7 # Organization: http://blog.znix.top
 8 # Created Time : 2017-12-07 10:53:38
 9 # Description:
10 #############################################################
11 . /etc/init.d/functions
12 
13 JinChen=`ps -ef |grep -c  [n]ginx`
14 QiDong='/server/scripts/nginx.sh start'
15 StatuS=`curl -I -w "%{http_code}\n" -o /dev/null -s   10.0.0.180`
16 StatuS2=`curl -s 10.0.0.180/check.html|grep -c ok`
17 StartNginx='/server/scripts/nginx.sh start'
18 
19 if [ $JinChen -ge 2  ]
20   then 
21     if [ "$StatuS" -eq 200 ]
22       then
23         if [ "$StatuS2" -eq 1 ]
24           then
25             action "Nginx 服务运行正常" /bin/true
26           else
27             action "请检查chenk.html文件!" /bin/false
28         fi
29     else
30       action "请检查首页文件!" /bin/false
31     fi
32 else
33     action "Nginx 未正常运行!" /bin/false
34     $StartNginx    
35 fi
View Code web 监控脚本内容
复制代码

脚本执行过程:

 

1.3 case条件结构语句

1.3.1 case语法结构

复制代码
case "字符串变量" in 
  值1)
     指令1
     ;;
  值2)
     指令2
     ;;
  值*)
     指令
esac
复制代码

1.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
复制代码

1.3.3 case值的书写方式

apple)

      echo -e "$RED_COLOR apple $RES"

      ;;

也可以这样写,输入2种格式找同一个选项

apple|APPLE)

      echo -e "$RED_COLOR apple $RES"

      ;;

1.3.4 case语句小结

    😋 case语句就相当于多分支的if语句。case语句的优势是更规范、易读。

    😋 case语句适合变量的值少,且为固定的数字或字符串集合。(1,2,3)或(start,stop,restart)。

      😋 系统服务启动脚本传参的判断多用case语句,多参考rpcbind/nfs/crond脚本;菜单脚本也可以使用case

1.3.5 【练习题1】使用case编写一个菜单脚本

脚本内容

复制代码
 1 [root@clsn case]# cat menu.sh 
 2 #!/bin/bash
 3 #############################################################
 4 # File Name: menu.sh
 5 # Version: V1.0
 6 # Author: clsn
 7 # Organization: http://blog.znix.top
 8 # Created Time : 2017-12-07 14:47:36
 9 # Description:
10 #############################################################
11 
12 
13 cat<<EOF
14 1. install rsync
15 2. install nfs
16 3. install mysql
17 4. install all
18 EOF
19 
20 read -p '请输入你的选择:' chs
21 
22 case $chs in
23   1)
24    echo install rsync success
25    ;;
26   2)
27    echo install nfs success
28    ;;
29   3)
30    echo install mysql success
31    ;;
32   4)
33    echo install rsync/nfs/mysql success
34    ;;
35   *)
36    echo "你输入有误"
37 esac
View Code 菜单脚本内容
复制代码

脚本执行过程:

 

1.3.6 【练习题2】输出带有颜色的水果菜单

脚本内容:

复制代码
 1 [root@clsn scripts]# cat fruits.sh 
 2 #!/bin/bash
 3 #############################################################
 4 # File Name: fruits.sh
 5 # Version: V1.0
 6 # Author: clsn
 7 # Organization: http://blog.znix.top
 8 # Created Time : 2017-12-06 21:23:31
 9 # Description:
10 #############################################################
11 cat <<EOF
12 =======================
13 1.apple
14 2.pear
15 3.banana
16 4.exit
17 =======================
18 EOF
19 read -t 10 -p  "你要看什么水果:" Menu_Num
20 
21 case "$Menu_Num" in 
22   1)
23    echo -e "\033[31m apple \033[0m"
24    ;;
25   2)
26    echo -e "\033[32m pear \033[0m"
27    ;;
28   3)
29    echo -e "\033[33m banana \033[0m" 
30    ;;
31   4)
32    exit
33 esac
View Code 水果菜单脚本
复制代码

脚本执行过程:

 

1.3.7 写脚本规范及注意事项

  1.变量名称不能和系统已经存在的命令等重复  free  == > Free

  2. 判断单位要统一

  3. 脚本一行不超过一屏的一半。

  4. 能写成变量的内容尽量写成变量

1.4 练习题

1.4.1 【练习题1】监控Memcached缓存服务是否正常

  监控Memcached缓存服务是否正常,模拟用户(web客户端)检测。

  使用nc命令加上set/get来模拟检测。

    memecached安装:http://www.cnblogs.com/clsn/p/7999510.html

脚本内容:

复制代码
 1 [root@clsn scripts]# vim  memcache_check.sh 
 2 #!/bin/bash
 3 #############################################################
 4 # File Name: memcache_check.sh
 5 # Version: V1.0
 6 # Author: clsn
 7 # Organization: http://blog.znix.top
 8 # Created Time : 2017-12-07 15:50:03
 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 clsn2017 0 10 8\r\nclsn2018\r\n"|nc 10.0.0.180 11211'
15 Get_Key='printf "get clsn2017\r\n" |nc 10.0.0.180 11211 |grep -c clsn2018'
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
View Code 监控 memcached脚本
复制代码

脚本执行过程

 

1.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@clsn scripts]# cat rsyncd 
 2 #!/bin/bash
 3 #############################################################
 4 # File Name: rsync_admin.sh
 5 # Version: V1.0
 6 # Author: clsn
 7 # Organization: http://blog.znix.top
 8 # Created Time : 2017-12-07 18:39:37
 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
View Code rsync 服务管理脚本
复制代码

脚本执行过程

 

1.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@clsn scripts]# cat menu.sh 
 2 #!/bin/bash
 3 #############################################################
 4 # File Name: menu.sh
 5 # Version: V1.0
 6 # Author: clsn
 7 # Organization: http://blog.znix.top
 8 # Created Time : 2017-12-07 19:29:30
 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
View Code 自动化软件部署脚本
复制代码

执行过程

 

1.4.4 if 与 case 对比

  if 语句类似黑名单,需要把这种错误场景封堵

  case 语句类似白名单,只要把正确结果列完整即可

1.5 其他补充说明

1.5.1 linux中产生随机数的方法

[root@clsn scripts]# echo $RANDOM 
29291
[root@clsn scripts]# echo $RANDOM 
5560
[root@clsn scripts]# echo $RANDOM 
2904

1.5.2 echo 命令输出带颜色字符

# 彩色字体

echo -e "\033[30m 黑色字 clsn \033[0m"
echo -e "\033[31m 红色字 clsn \033[0m"
echo -e "\033[32m 绿色字 clsn \033[0m"
echo -e "\033[33m 黄色字 clsn \033[0m"
echo -e "\033[34m 蓝色字 clsn \033[0m"
echo -e "\033[35m 紫色字 clsn \033[0m"
echo -e "\033[36m 天蓝字 clsn \033[0m"
echo -e "\033[37m 白色字 clsn \033[0m"

效果示意图

 

# 彩色底纹

echo -e "\033[40;37m 黑底白字 clsn \033[0m"
echo -e "\033[41;37m 红底白字 clsn \033[0m"
echo -e "\033[42;37m 绿底白字 clsn \033[0m"
echo -e "\033[43;37m 黄底白字 clsn \033[0m"
echo -e "\033[44;37m 蓝底白字 clsn \033[0m"
echo -e "\033[45;37m 紫底白字 clsn \033[0m"
echo -e "\033[46;37m 天蓝白字 clsn \033[0m

效果示意图

 

# 特效字体

复制代码
\033[0m 关闭所有属性
\033[1m 设置高亮度
\033[4m 下划线
\033[5m 闪烁
\033[7m 反显
\033[8m 消隐
\033[30m — \033[37m 设置前景色
\033[40m — \033[47m 设置背景色
\033[nA 光标上移 n 行
\033[nB 光标下移 n 行
\033[nC 光标右移 n 行
\033[nD 光标左移 n 行
\033[y;xH 设置光标位置
\033[2J 清屏
\033[K 清除从光标到行尾的内容
\033[s 保存光标位置
\033[u 恢复光标位置
\033[?25l 隐藏光标
\033[?25h 显示光标
复制代码

部分效果示意图

 

1.5.3 显示文本中的隐藏字符

使用cat命令查看文本中的隐藏字符

复制代码
[root@clsn ~]# cat --help
用法:cat [选项]... [文件]...
将[文件]或标准输入组合输出到标准输出。

  -A, --show-all           等于-vET
  -b, --number-nonblank    对非空输出行编号
  -e                       等于-vE
  -E, --show-ends          在每行结束处显示"$"
  -n, --number             对输出的所有行编号
  -s, --squeeze-blank      不输出多行空行
  -t                       与-vT 等价
  -T, --show-tabs          将跳格字符显示为^I
  -u                       (被忽略)
  -v, --show-nonprinting   使用^ 和M- 引用,除了LFD和 TAB 之外
复制代码

使用cat -A查看隐藏的字符

[root@clsn ~]# cat -A /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4$
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6$
10.0.0.1 mirrors.aliyuncs.com mirrors.aliyun.com$
10.0.0.180 clsn$

关于隐藏字符常见错误

在windows中编写的脚本换行使用的是 \r\n

         但是在linux中使用\n 进行换行

[root@clsn ~]# cat -A windowe.sh 
n1=2^M$
n2=1^M$
^M$
[ $n1 -gt $n2 ] && echo "$n1 > $n2" && exit^M$
[ $n1 -eq $n2 ] && echo "$n1 = $n2" && exit^M$
echo "$n1 < $n2"^M$

使用dos2unix 把windows上的脚本转化linux格式

[root@clsn ~]# dos2unix windowe.sh 
dos2unix: converting file windowe.sh to Unix format ...

转换后,脚本的内容隐藏内容改变。

[root@clsn ~]# cat -A windowe.sh 
n1=2$
n2=1$
$
[ $n1 -gt $n2 ] && echo "$n1 > $n2" && exit$
[ $n1 -eq $n2 ] && echo "$n1 = $n2" && exit$
echo "$n1 < $n2"$

1.5.4 排错技巧

sh -x  脚本.sh

 -x 开启脚本调试模式

cat -A  文件.txt

-A  查看文件的隐藏字符

1.5.5 shell 脚本段注释方法

方法一:

<<EOF
  内容
EOF

方法二:

一行注释方法 → : '内容'
段注释方法 ↓
:' 
 http://blog.znix.top
'

:命令的说明

[root@clsn scripts]# help :
:: :
    空的命令。
    
    没有效果; 此命令不做任何操作。
    
    退出状态:
    总是成功。

:命令的应用场景

if 条件
  then 
    :
else
    命令
fi

1.5.6 其他补充

  类进度条效果

yum install -y pv 
echo {1..20}|pv -qL 15

  clear 命令

清屏 == ctrl + l

1.6 参考文献

http://man.linuxde.net/curl
https://www.abcdocker.com/abcdocker/206
http://www.cnblogs.com/clsn/p/7750615.html
http://blog.51cto.com/oldboy/1867160 (部分练习题目来源)

  本文出自“惨绿少年”,欢迎转载,转载请注明出处!http://blog.znix.top

 

posted @   惨绿少年  阅读(34395)  评论(7编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
1.1 条件表达式1.1.1 文件判断1.1.2 字符串判断1.1.3 整数判断1.1.4 逻辑符号1.1.5 【练习题】开发3个shell脚本比较2个整数大小1.2 if条件语句1.2.1 三种语法1.2.2 if条件语句小结1.2.3 【练习题1】输入2个数字,比较大小(使用if语句结合条件表达式实现) 1.2.4 【练习题2】系统内存低于100M邮件报警,加入计划任务,3分钟检查一次。1.2.5 【练习题3】模拟编写启动nginx脚本1.2.6 【练习题5】Web及MySQL服务异常监测案例1.3 case条件结构语句1.3.1 case语法结构1.3.2 case与if的对比1.3.3 case值的书写方式1.3.4 case语句小结1.3.5 【练习题1】使用case编写一个菜单脚本1.3.6 【练习题2】输出带有颜色的水果菜单1.3.7 写脚本规范及注意事项1.4 练习题1.4.1 【练习题1】监控Memcached缓存服务是否正常1.4.2 【练习题2】使用(case)编写rsync管理脚本1.4.3 【练习题3】菜单自动化软件部署脚本实践1.4.4 if 与 case 对比1.5 其他补充说明1.5.1 linux中产生随机数的方法1.5.2 echo 命令输出带颜色字符1.5.3 显示文本中的隐藏字符1.5.4 排错技巧1.5.5 shell 脚本段注释方法1.5.6 其他补充1.6 参考文献
点击右上角即可分享
微信分享提示