美文网首页
shell编程二

shell编程二

作者: XiaoMing丶 | 来源:发表于2019-01-11 23:01 被阅读0次

目录

一、shell中的函数
二、shell中的数组
三、shell告警系统

一、shell中的函数

函数就是把一段代码整理到了一个小单元中,并给这个小单元起一个名字,当用到这段代码时直接调用这个小单元的名字即可。

函数格式:
 function f_name() {   ##可以省略function
                       command
                 }
##函数名不要和shell关键词一样
##定义好的函数直接使用函数名调用

 示例一

[root@minglinux-01 /usr/local/sbin] cat function1.sh 
#!/bin/bash
function inp(){
    echo "The first par is $1"
    echo "The second par is $2"
    echo "The third par is $3"
    echo "The script name is $0"
    echo "The quantity of par is $#"
}
inp a b 1 2 3
[root@minglinux-01 /usr/local/sbin] sh function1.sh 
The first par is a
The second par is b
The third par is 1
The script name is function1.sh
The quantity of par is 5

 示例二

##计算1+2
[root@minglinux-01 /usr/local/sbin] cat function2.sh 
#!/bin/bash
sum() {
    s=$[$1+$2]
    echo $s
}
sum 1 2
[root@minglinux-01 /usr/local/sbin] sh function2.sh 
3

 示例三

##需求:交互方式输入网卡名后打印该网卡的IP地址
[root@minglinux-01 ~] ifconfig |grep -A1 "ens33"
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.162.130  netmask 255.255.255.0  broadcast 192.168.162.255
[root@minglinux-01 ~] ifconfig |grep -A1 "ens33"|tail -1
        inet 192.168.162.130  netmask 255.255.255.0  broadcast 192.168.162.255
[root@minglinux-01 ~] ifconfig |grep -A1 "ens33"|tail -1|awk '{print $1}'
inet
[root@minglinux-01 ~] ifconfig |grep -A1 "ens33"|tail -1|awk '{print $2}'
192.168.162.130
##编写脚本如下
[root@minglinux-01 /usr/local/sbin] cat function3.sh 
#!/bin/bash
ip(){
 
    ifconfig |grep -A1 "$1:"|tail -1|awk '{print $2}'
}

read -p "Please input the eth name: " eth 
ip $eth

[root@minglinux-01 /usr/local/sbin] sh function3.sh 
Please input the eth name: ens33
192.168.162.130
[root@minglinux-01 /usr/local/sbin] sh function3.sh 
Please input the eth name: lo
127.0.0.1

二、shell中的数组

定义数组的格式: arr_name=(value1 value2 value3 ...)
调用格式为:${arr_name[@]},
方括号中的 @ 表示所有的元素,也可以用 * 代替
调用数组中某一个元素需要使用元素的下标, 下标从0开始

[root@minglinux-01 /usr/local/sbin] arr=(first second third)
[root@minglinux-01 /usr/local/sbin] echo $arr
first
[root@minglinux-01 /usr/local/sbin] echo ${arr[@]}
first second third
[root@minglinux-01 /usr/local/sbin] echo ${arr[*]}
first second third
[root@minglinux-01 /usr/local/sbin] echo ${arr[0]}
first
[root@minglinux-01 /usr/local/sbin] echo ${arr[2]}
third
[root@minglinux-01 /usr/local/sbin] echo ${#arr[@]} #获取数组元素个数
3
#数组的赋值
[root@minglinux-01 /usr/local/sbin] arr[3]=fourth
[root@minglinux-01 /usr/local/sbin] echo ${arr[@]}
first second third fourth
[root@minglinux-01 /usr/local/sbin] arr[3]=4
[root@minglinux-01 /usr/local/sbin] echo ${arr[@]}
first second third 4
#数组的删除
[root@minglinux-01 /usr/local/sbin] unset arr[3] ##删除数组元素
[root@minglinux-01 /usr/local/sbin] echo ${arr[@]}
first second third
[root@minglinux-01 /usr/local/sbin] unset arr ##删除数组
[root@minglinux-01 /usr/local/sbin] echo ${arr[@]}

#数组的分片
[root@minglinux-01 /usr/local/sbin] arr=(`seq 1 10`)
[root@minglinux-01 /usr/local/sbin] echo ${arr[@]}
1 2 3 4 5 6 7 8 9 10
[root@minglinux-01 /usr/local/sbin] echo ${arr[@]:0:5} #从第一个元素开始截取5个
1 2 3 4 5
[root@minglinux-01 /usr/local/sbin] echo ${arr[@]:0-3:3} #从倒数第三个开始截取3个
8 9 10

#数组的替换
[root@minglinux-01 /usr/local/sbin] echo ${arr[@]/1/a} #仅替换输出内容,实际元素并未改变
a 2 3 4 5 6 7 8 9 a0
[root@minglinux-01 /usr/local/sbin] echo ${arr[@]}
1 2 3 4 5 6 7 8 9 10
[root@minglinux-01 /usr/local/sbin] arr=(${arr[@]/1/a}) #真正替换数组元素
[root@minglinux-01 /usr/local/sbin] echo ${arr[@]}
a 2 3 4 5 6 7 8 9 a0

三、shell告警系统

  • 告警系统需求分析

需求:使用shell定制各种个性化告警工具,但需要统一化管理、规范化管理。
需求场景:
 当监控项比较冷门时,zabbix等监控工具中不包含该监控项时,需要用户自定义监控脚本
 C/S架构中服务器与客户端网络出现问题,无法将监控数据上报服务端,可以编写用于监控的shell脚本,此时监控系统是分布式的,用户需要在每一台被监控的机器上编辑shell脚本,每一台机器都可以做到独立监控,不需要依赖其他机器
思路:指定一个脚本包,包含主程序、子程序、配置文件、邮件引擎、输出日志等。
 主程序:作为整个脚本的入口,是整个系统的命脉。
 配置文件:是一个控制中心,用它来开关各个子程序,指定各个相关联的日志文件。
 子程序:这个才是真正的监控脚本,用来监控各个指标。
 邮件引擎:是由一个python程序来实现,它可以定义发邮件的服务器、发邮件人以及发件人密码
 输出日志:整个监控系统要有日志输出。

要求:我们的机器角色多种多样,但是所有机器上都要部署同样的监控系统,也就说所有机器不管什么角色,整个程序框架都是一致的,不同的地方在于根据不同的角色,定制不同的配置文件。
 程序架构

                             (主目录 mon)
   ________________________________|_____________________________________
   |                |             |               |                     |
  bin             conf         shares            mail                  log
   |                |             |               |                     |
 [main.sh]    [mon.conf]  [load.sh sh] [mail.py mail.sh]   [mon.log err.log]

bin下是主程序
conf下是配置文件
shares下是各个监控脚本
mail下是邮件引擎
log下是日志
  • 告警系统主脚本
#创建主目录和子目录
[root@minglinux-01 /usr/local/sbin] mkdir mon
[root@minglinux-01 /usr/local/sbin] cd mon
[root@minglinux-01 /usr/local/sbin/mon] ls
[root@minglinux-01 /usr/local/sbin/mon] mkdir bin conf shares mail log
[root@minglinux-01 /usr/local/sbin/mon] ls
bin  conf  log  mail  shares
#创建主脚本
#主脚本用于判断某监控项是否需要监控,若需要监控则调用对应项的子脚本

 #!/bin/bash
#Written by aming.
# 是否发送邮件的总开关,send为1则以下所有监控项都会发送邮件,系统维护时应关闭
# export表示所有变量都会应用于子脚本中;
export send=1
# 过滤ip地址,告诉用户是哪一台机器发的告警
export addr=`ifconfig |grep -A1 "ens33: "|awk '/inet/ {print $2}'`
dir=`pwd`
# 只需要最后一级目录名
last_dir=`echo $dir|awk -F'/' '{print $NF}'`
# 下面的判断目的是,保证执行脚本的时候,我们在bin目录里,
# 不然监控脚本、邮件和日志很有可能找不到
if [ $last_dir == "bin" ] || [ $last_dir == "bin/" ]; then
    conf_file="../conf/mon.conf"
else
    echo "you shoud cd bin dir"
    exit
fi
exec 1>>../log/mon.log 2>>../log/err.log #输出正确和错误的日志
echo "`date +"%F %T"` load average"  
/bin/bash ../shares/load.sh #直接调用子脚本load.sh
#先检查配置文件中是否需要监控502
if grep -q 'to_mon_502=1' $conf_file; then
    export log=`grep 'logfile=' $conf_file |awk -F '=' '{print $2}' |sed 's/ //g'`
    /bin/bash  ../shares/502.sh
fi
  • 告警系统配置文件
[root@minglinux-01 /usr/local/sbin/mon/conf] vim mon.conf

  1 ## to config the options if to monitor
  2 ## 定义mysql的服务器地址、端口以及user、password
  3 to_mon_cdb=0   ##0 or 1, default 0,0 not monitor, 1 monitor
  4 db_ip=10.20.3.13
  5 db_port=3315
  6 db_user=username
  7 db_pass=passwd
  8 ## httpd   如果是1则监控,为0不监控
  9 to_mon_httpd=0
 10 ## php 如果是1则监控,为0不监控
 11 to_mon_php_socket=0
 12 ## http_code_502  需要定义访问日志的路径
 13 to_mon_502=1
 14 logfile=/data/log/xxx.xxx.com/access.log
 15 ## request_count   定义日志路径以及域名
 16 to_mon_request_count=0
 17 req_log=/data/log/www.discuz.net/access.log
 18 domainname=www.discuz.net
  • 告警系统监控项目
#load.sh内容如下
[root@minglinux-01 /usr/local/sbin/mon/shares] vim load.sh

  1 #!/bin/bash
  2 ##Writen by aming##
  3 load=`uptime |awk -F 'average:' '{print $2}'|cut -d',' -f1|sed 's/ //g' | cut -d. -f1`  ##获取最近一分钟的系统负载
  4 if [ $load -gt 10 ] && [ $send -eq "1" ] ##当系统负载高于10 且允许发邮件的情况下,发送报警邮件
  5 then
  6     echo "$addr `date +%T` load is $load" >../log/load.tmp
  7     /bin/bash ../mail/mail.sh 331601950@qq.com "$addr\_load:$load" `cat ../log/load.tmp`
  8 fi
  9 echo "`date +%T` load is $load"

#502.sh内容如下
[root@minglinux-01 /usr/local/sbin/mon/shares] vim 502.sh

  1 #!/bin/bash
  2 d=`date -d "-1 min" +%H:%M`  #变量d为一分钟前的时间
  3 c_502=`grep :$d:  $log  |grep ' 502 '|wc -l`
  4 if [ $c_502 -gt 10 ] && [ $send == 1 ]; then
  5      echo "$addr $d 502 count is $c_502">../log/502.tmp
  6      /bin/bash ../mail/mail.sh $addr\_502 $c_502  ../log/502.tmp
  7 fi
  8 echo "`date +%T` 502 $c_502"
#disk.sh内容如下
[root@minglinux-01 /usr/local/sbin/mon/shares] vim disk.sh

  1 #!/bin/bash
  2 ##Writen by aming##
  3 rm -f ../log/disk.tmp
  4 for r in `df -h |awk -F '[ %]+' '{print $5}'|grep -v Use`
  5 do
  6     if [ $r -gt 90 ] && [ $send -eq "1" ]
  7 then
  8     echo "$addr `date +%T` disk useage is $r" >>../log/disk.tmp
  9 fi
 10 if [ -f ../log/disk.tmp ]
 11 then
 12     df -h >> ../log/disk.tmp
 13     /bin/bash ../mail/mail.sh $addr\_disk $r ../log/disk.tmp
 14     echo "`date +%T` disk useage is nook"
 15 else
 16     echo "`date +%T` disk useage is ok"
 17 fi

[root@minglinux-01 /usr/local/sbin/mon/shares] df -h
文件系统        容量  已用  可用 已用% 挂载点
/dev/sda3        28G  7.5G   21G   27% /
devtmpfs        901M     0  901M    0% /dev
tmpfs           911M     0  911M    0% /dev/shm
tmpfs           911M  9.6M  902M    2% /run
tmpfs           911M     0  911M    0% /sys/fs/cgroup
tmpfs           911M     0  911M    0% /tmp
/dev/sda1       197M  140M   58M   71% /boot
tmpfs           183M     0  183M    0% /run/user/0
[root@minglinux-01 /usr/local/sbin/mon/shares] df -h |awk -F '[ %]+' '{print $5}'|grep -v Use 
#以一个或多个空格和百分号作为分隔符
已用
27
0
0
2
0
0
71
0

#当语言被修改为en时,最上面一行将显示为英文
[root@minglinux-01 /usr/local/sbin/mon/shares] echo $LANG
zh_CN.UTF-8
[root@minglinux-01 /usr/local/sbin/mon/shares] LANG=en
[root@minglinux-01 /usr/local/sbin/mon/shares] df -h |awk -F '[ %]+' '{print $5}'|grep -v Use
27
0
0
2
0
0
71
0
  • 告警系统邮件引擎
[root@minglinux-01 /usr/local/sbin/mon/shares] cp /usr/lib/zabbix/alertscripts/mail.py ../mail/mail.py
#拷贝之前的mail.py

#mail.sh内容如下,用于告警收敛
 [root@minglinux-01 /usr/local/sbin/mon/shares] vim mail.sh

  1 #!/bin/bash
  2 log=$1 #每次执行脚本发邮件都要查找监控项对应的日志
  3 t_s=`date +%s`
  4 t_s2=`date -d "2 hours ago" +%s`
  #2个小时前的时间戳,第一次执行脚本时必须报警,要保证两个时间戳的差值足够大可以满足报警条件
  5 if [ ! -f /tmp/$log ]
  6 then
  7     echo $t_s2 > /tmp/$log #若监控项目日志文件不存在,则创建日志并在日志第一行写入2小时前的时间戳
  8 fi
  9 t_s2=`tail -1 /tmp/$log|awk '{print $1}'`  #日志文件中最后一行的内容作赋值给t_s2,如果是文件刚创建的情况则为第一行(第一行也是最后一行)
 10 echo $t_s>>/tmp/$log #将当前时间的时间戳追加到/tmp/$log中
 11 v=$[$t_s-$t_s2]  #两次时间戳差值
 12 echo $v 
 13 if [ $v -gt 3600 ] #差值大于3600则执行后续操作
 14 then  
 15     ./mail.py  $1  $2  $3
 16     echo "0" > /tmp/$log.txt
 17 else  ##时间戳差值不大于3600,则执行以下操作
 18     if [ ! -f /tmp/$log.txt ]  #log.txt是计数器,若log.txt不存在
 19     then
 20         echo "0" > /tmp/$log.txt
 21     fi
 22     nu=`cat /tmp/$log.txt`
 23     nu2=$[$nu+1] #
 24     echo $nu2>/tmp/$log.txt
 25     if [ $nu2 -gt 10 ] #若计数器的值超过10,再次发出告警
 26     then
 27          ./mail.py  $1 "trouble continue 10 min $2" "$3"
 28          echo "0" > /tmp/$log.txt  #发出告警后将计数器$log.txt重新计数,重置为0
 29     fi
 30 fi
 
  • 运行告警系统

#可以设置定时任务

[root@minglinux-01 /usr/local/sbin/mon/shares] crontab -e
no crontab for root - using an empty one

* * * * * cd /usr/local/sbin/mon/bin; bash main.sh  #每分钟执行一次

相关文章

  • shell 案例

    Shell编程一 Shell防范ARP攻击 Shell编程二 Shell防范DDos攻击 Shell编程三 ...

  • BigData~01:Shell

    Shell编程基础 内容大纲 一、Shell编程二、高级文本处理命令:sed、awk、cut三、crontab定时...

  • shell 第一天

    shell编程初识 1.1 shell编程初识 shell的定义 Shell 是命令解释器 Shell 也是...

  • Shell编程系列(三)-- 运算符

    前言 在上一篇文章Shell编程系列(二)-- Bash 变量中, 我们学习了Shell编程中的变量相关的知识。...

  • shell编程(二)

    变量 局部变量 环境变量-----export 一个用户的所有进程中都可以访问的变量 环境变量的命令一...

  • shell编程(二)

    一、字符串比对 字符串必须使用双引号-n //nozero 字符串长度不为0时为真-z //zero 字符串长度为...

  • shell编程(二)

    样例 注意:shell代码中linux命令中有交互命令的,以<<EOF开头,以EOF结尾。中间写交互命令,命令要顶...

  • shell编程二

    目录 一、shell中的函数二、shell中的数组三、shell告警系统 一、shell中的函数 函数就是把一段代...

  • 78.shell编程

    shell编程 Shell脚本,是一种为shell编写的脚本程序。 Shell编程跟JavaScript、Pyth...

  • 2019-01-25

    Linux系统Shell编程指南 前言 适合人群:有类似C编程基础的人 一、Shell编程介绍 Shell解释型语...

网友评论

      本文标题:shell编程二

      本文链接:https://www.haomeiwen.com/subject/votmrqtx.html