20.16-20.19 shell:函數、數組,告警系統需求分析

20.16/20.17 shell中的函數

函數,是一個子shell,代碼段,定義完函數後可以引用它。

函數就是把一段代碼整理到了一個小單元中,並給這個小單元起一個名字,當用到這段代碼時直接調用這個小單元的名字即可。

function f_name(){
command
}

函數必須要放在最前面

示例1

1 編寫腳本

#!/bin/bash
function inp() {
  echo $1 $2  $3 $0 $#
}
inp 1 a 2


解釋:

#!/bin/bash

function inp() {inp        是參數的名字

  echo $1 $2 $3 $0 $#       $1第一個參數,$2第二個參數,$3第三個參數,$0文件的名字,$#統計參數

}

inp 1 a 2            輸入函數名稱inp直接調用函數,輸出結果是 $1=a $2=a $3=2


2 執行輸出

[root@AliKvn shell]# sh fun1.sh 
1 a 2 fun1.sh 3
[root@AliKvn shell]# sh -x fun1.sh 
+ inp 1 a 2
+ echo 1 a 2 fun1.sh 3
1 a 2 fun1.sh 3


編寫第二種腳本

[root@AliKvn shell]# vim fun1.sh 
#!/bin/bash
function inp() {
  echo "the first par is $1" 
  echo "the second par is $2"
  echo "the triple par is $3" 
  echo "the script is $0"
  echo "total par is $#"
}
inp 1 a 2 3 adf

參數解釋:

inp 1 a 2 3 adf 調用inp的時候,由於沒有調用$4 $5,所以這裏第四個參數3 第五個參數adf是不會顯示的,因爲函數沒有執行他們。


以上腳本,正確的輸出結果應該是與echo裏面除了$參數之外的參數對應,就是說 正常的話 應該輸出是對應的.

執行過程

[root@AliKvn shell-re]# sh fun1.sh
the first par is 1
the second par is a
the triple par is 2
the script is fun1.sh
total par is 5
[root@AliKvn shell-re]# sh -x fun1.sh
+ inp 1 a 2 3 adf
+ echo 'the first par is 1'
the first par is 1
+ echo 'the second par is a'
the second par is a
+ echo 'the triple par is 2'
the triple par is 2
+ echo 'the script is fun1.sh'
the script is fun1.sh
+ echo 'total par is 5'
total par is 5

另一種編寫方法,輸出$1

[root@AliKvn shell]# vim fun2.sh 
#!/bin/bash
function inp() {
  echo "the first par is $1" 
  echo "the second par is $2"
  echo "the triple par is $3" 
  echo "the script is $0"
  echo "total par is $#"
}
inp $1 $2 $3

解釋:

inp $1 $2 $3    $1表示fun2.sh的第一個參數,$2表示fun2.sh的第二個參數,$3表示fun2.sh的第三個參數...

sh fun2.sh執行過程

[root@AliKvn shell-re]# sh fun2.sh 1
the first par is 1
the second par is
the tri par is
the script name is fun2.sh
total number is 1

[root@AliKvn shell-re]# sh fun2.sh 1 2
the first par is 1
the second par is 2
the tri par is
the script name is fun2.sh
total number is 2

[root@AliKvn shell-re]# sh fun2.sh 1 2 3
the first par is 1
the second par is 2
the tri par is 3
the script name is fun2.sh
total number is 3


示例2 

用意環境這個函數用來定義加法


編寫腳本

#!/bin/bash
sum() {
        s=$[$1+$2]
        echo $s
}
sum 1 10



腳本解釋:

s=$[$1+$2]  函數的第一個參數跟第二個參數相加

sum 1 10    調用sum函數,$1+$2=1+10,因爲第一個函數1 第二個是10

腳本整個意思就是, s=$[$1+$2]兩個函數相加$1+$2(相當於1+10),最後把$s打印出來,其實$s就是他們相加的和


示例3

用意環境:用來顯示IP地址的腳本.


編寫腳本

#!/bin/bash/
ip()
{
ifconfig |grep -A1 "$1: " |awk '/inet/ {print $2}'
}
read -p "plz input the eth name: " eth
ip $eth

解釋:

ifconfig |grep -A1 "$1: " |awk '/inet/ {print $2}'

用$1參數是針對用於多網卡之下使用,如果只有一個網卡的話,這裏寫網卡名字就可以.


腳本動作分解,

執行#ifconfig的內容

[root@centos7-01 ~]# ifconfig 
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.189.128  netmask 255.255.255.0  broadcast 192.168.189.255
        inet6 fe80::20c:29ff:fe15:5353  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:15:53:53  txqueuelen 1000  (Ethernet)
        RX packets 84  bytes 10800 (10.5 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 142  bytes 15337 (14.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.189.150  netmask 255.255.255.0  broadcast 192.168.189.255
        ether 00:0c:29:15:53:53  txqueuelen 1000  (Ethernet)
ens37: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.149.147  netmask 255.255.255.0  broadcast 192.168.149.255
        inet6 fe80::df58:834c:af48:5f38  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:15:53:5d  txqueuelen 1000  (Ethernet)
        RX packets 1  bytes 243 (243.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 15  bytes 1134 (1.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1  (Local Loopback)
        RX packets 2252  bytes 691000 (674.8 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2252  bytes 691000 (674.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
下面以ens33爲例

#執行# ifconfig |grep -A1 "ens33: ",因爲ens33有2個網卡,所以也會把ens33:0給過濾出來
#表示過濾"ens33"這一行,包括和它下一行
[root@centos7-01 ~]# ifconfig |grep -A1 "ens33: "
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.189.128  netmask 255.255.255.0  broadcast 192.168.189.255
--
ens33:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.189.150  netmask 255.255.255.0  broadcast 192.168.189.255

#不過濾ens33:0,執行# ifconfig |grep -A1 "ens33: "
[root@centos7-01 ~]# ifconfig |grep -A1 "ens33: "
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.189.128  netmask 255.255.255.0  broadcast 192.168.189.255

#ip地址是inet這行,所以,只需過濾這行信息出來
[root@centos7-01 ~]# ifconfig |grep -A1 "ens33: " |grep 'inet'
        inet 192.168.189.128  netmask 255.255.255.0  broadcast 192.168.189.255

#截取過濾了inet這行出來了,下面需要把想要的ip地址給過濾出來
192.168.189.128是我需要的信息,那麼它屬於第二個字段,所以可以利用awk把它分割過濾出來
[root@centos7-01 ~]# ifconfig |grep -A1 "ens33: " |grep 'inet' |awk '{print $2}'
192.168.189.128

#或者將後面直接grep的用法換成awk
[root@centos7-01 ~]# ifconfig |grep -A1 "ens33: " |awk '/inet/ {print $2}'
192.168.189.128


執行過程:

[root@centos7-01 shell]# sh -x fun3.sh 
+ read -p 'plz input the eth name: ' eth
plz input the eth name: ens33    
+ ip ens33
+ ifconfig
+ grep -A1 'ens33: '
+ awk '/inet/ {print $2}'
192.168.189.128
[root@centos7-01 shell]# sh -x fun3.sh 
+ read -p 'plz input the eth name: ' eth
plz input the eth name: ens33:0
+ ip ens33:0
+ ifconfig
+ grep -A1 'ens33:0: '
+ awk '/inet/ {print $2}'
192.168.189.150
[root@centos7-01 shell]# sh -x fun3.sh 
+ read -p 'plz input the eth name: ' eth
plz input the eth name: ens37    
+ ip ens37
+ ifconfig
+ grep -A1 'ens37: '
+ awk '/inet/ {print $2}'
192.168.149.147


課後練習:

給此腳本添加2個判斷條件:

輸入的網卡名稱是否存在本機

輸入的網卡有沒有ip地址


20.18 shell中的數組


shell中的數組1 


定義數組 a=(1 2 3); 

打印方法 echo ${a[@]}

[root@centos7-01 shell]# a=(1 2 3)
[root@centos7-01 shell]# echo ${a[@]}
1 2 3

用*可以代替@,不影響輸出,效果一樣

[root@centos7-01 shell]# echo ${a[*]}
1 2 3

查看某個參數值,0表示第一個

[root@centos7-01 shell]# echo ${a[1]}
2
[root@centos7-01 shell]# echo ${a[2]}
3
[root@centos7-01 shell]# echo ${a[0]}
1

echo ${#a[@]} 獲取數組的元素個數 

[root@centos7-01 shell]# echo ${#a[*]}
4



數組賦值

[root@centos7-01 shell]# a[3]=b

打印

[root@centos7-01 shell]# echo ${a[*]}
1 2 3 b

同樣,賦值也支持覆蓋,更改

[root@centos7-01 shell]# a[3]=bbbb
[root@centos7-01 shell]# echo ${a[*]}
1 2 3 bbbb

a[5]=2; echo ${a[@]} 如果下標不存在則會自動添加一個元素


數組的刪除

刪除a的第四個參數

[root@centos7-01 shell]# unset a[3]
[root@centos7-01 shell]# echo ${a[*]}
1 2 3


刪除整個數組a

[root@centos7-01 shell]# unset a
[root@centos7-01 shell]# echo ${a[*]}


shell中的數組2 

數組分片

a=(`seq 1 10`) 可以 1 循環到 10

[root@centos7-01 shell]# a=(`seq 1 10`)
[root@centos7-01 shell]# echo ${a[*]}
1 2 3 4 5 6 7 8 9 10

上面的輸出,截取4-7的數字

[root@centos7-01 shell]# echo ${a[@]:3:4}
4 5 6 7

解釋:

# echo ${a[@]:3:4}

因爲從4開始截取,4的前面是3,且3是第三個,然後截取3後面的4個參數。


倒數截取

倒數3個數,截取2個(倒數是負數,所以是0- 表示,截取是從左到右)

[root@centos7-01 shell]# echo ${a[@]:0-3:2}
8 9

數組替換

例子:echo ${a[@]/7/6}  7是需要替換的值,6是被替換的值

[root@centos7-01 shell]# echo ${a[*]}
1 2 3 4 5 6 7 8 9 10
[root@centos7-01 shell]# echo ${a[*]/7/6}
1 2 3 4 5 6 6 8 9 10

同樣,可以給a賦值爲輸出後的參數

[root@centos7-01 shell]# echo ${a[*]/7/6}
1 2 3 4 5 6 6 8 9 10
[root@centos7-01 shell]# a=(${a[*]/7/6})
[root@centos7-01 shell]# echo ${a[*]}
1 2 3 4 5 6 6 8 9 10

輸出結果一樣


20.19 告警系統需求分析


shell項目-告警系統 

  • 需求:使用shell定製各種個性化告警工具,但需要統一化管理、規範化管理

  • 思路:指定一個腳本包,包含主程序、子程序、配置文件、郵件引擎、輸出日誌等。

  • 主程序:作爲整個腳本的入口,是整個系統的命脈。

  • 配置文件:是一個控制中心,用它來開關各個子程序,指定各個相關聯的日誌文件。

  • 子程序:這個纔是真正的監控腳本,用來監控各個指標。

  • 郵件引擎:是由一個python程序來實現,它可以定義發郵件的服務器、發郵件人以及發件人密碼。

  • 輸出日誌:整個監控系統要有日誌輸出。


要求:我們的機器角色多種多樣,但是所有機器上都要部署同樣的監控系統,也就說所有機器不管什麼角色,整個程序框架都是一致的,不同的地方在於根據不同的角色,定製不同的配置文件。

程序架構:

blob.png


  • bin下是主程序

  • conf下是配置文件

  • shares下是各個監控腳本

  • mail下是郵件引擎

  • log下是日誌


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章