20.16 shell中的函數(上)
函數就是一段代碼整理到了一個小單元中,給這個小單元起一個名字,用到這段代碼時直接調用這個小單元即可
一般函數格式:
function f_name(){
command
}
定義的函數名最好不與shell中的關鍵詞衝突(for、while、do等);
後期需要調用某個函數時直接敲函數名即可;
[root@hyc-01-01 shell]# vim function.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 b b c e f
[root@hyc-01-01 shell]# sh -x function.sh
+ inp b b c
+ echo 'the first par is b'
the first par is b
+ echo 'the second par is b'
the second par is b
+ echo 'the third par is c'
the third par is c
+ echo 'the script name is function.sh'
the script name is function.sh
+ echo 'the quantity of par is 5'
the quantity of par is 5
$後跟數字表示第幾個參數,如$1表示函數inp()的第一個參數;
$0表示腳本名稱;
共有3個參數;
打印出的信息中,$1爲1,$2爲a,$3爲2,$#會統計參數的個數;
[root@hyc-01-01 shell]# vim function.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 $1 $2 $3
此時寫在inp()函數外面的$1,$2,$3表示腳本function.sh的第一、第二、第三個參數
[root@hyc-01-01 shell]# sh -x function.sh 1
+ inp 1
+ echo 'the first par is 1'
the first par is 1
+ echo 'the second par is '
the second par is
+ echo 'the third par is '
the third par is
+ echo 'the script name is function.sh'
the script name is function.sh
+ echo 'the quantity of par is 1'
the quantity of par is 1
執行腳本時指定一個參數1;
結果顯示此時第一個參數爲1,其餘參數爲空;
參數總共只有一個;
20.17 shell中的函數(下)
若想調用某個函數那麼在調用語句之前必須先定義該函數
計算1+10:
[root@hyc-01-01 shell]# vim sum.sh
#!/bin/bash
sum() {
s=$[$1+$2]
echo $s
}
sum 1 10
[root@hyc-01-01 shell]# sh -x sum.sh
+ sum 1 10
+ s=11
+ echo 11
11
[root@hyc-01-01 shell]# ifconfig|grep -A1 "ens33: "|awk '/inet/ {print $2}'
[root@hyc-01-01 shell]# ifconfig|grep -A1 "ens33: "|grep 'inet' |awk '{print $2}'
192.168.31.129
[root@hyc-01-01 shell]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.31.129 netmask 255.255.255.0 broadcast 192.168.31.255
inet6 fe80::d46b:4589:4da1:2f34 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:4d:9d:95 txqueuelen 1000 (Ethernet)
RX packets 42396 bytes 3599222 (3.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 53172 bytes 18299829 (17.4 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
…
寫腳本時應不斷對腳本進行調試,直到得到預想的結果;
ifconfig|grep -A1 "ens33: "表示過濾出包含ens33的行以及它的下一行;
這裏爲ens33:後跟一個空格,這樣可以過濾掉像ens33:0:這樣的網卡;
awk:
grep 'inet' |awk '{print $2}' 過濾出包含inet的行,截取第二段
awk '/inet/ {print $2}'過濾出包含inet的行,截取第二段
輸入網卡名判斷網卡ip:
[root@hyc-01-01 shell]# vim ip.sh
#!/bin/bash
ip()
{
ifconfig|grep -A1 "$1: "|awk '/inet/ {print $2}'
}
read -p "please input the eth name " eth
ip $eth
[root@hyc-01-01 shell]# sh -x ip.sh
+ read -p 'please input the eth name ' eth
please input the eth name ens33
+ ip ens33
+ ifconfig
+ grep -A1 'ens33: '
+ awk '/inet/ {print $2}'
192.168.31.129
改進腳本:
1 若輸入的網卡不存在如何處理?
2 輸入的網卡無ip如何處理?
20.18 shell中的數組
數組:由一串字符串或數字形成的變量
定義數組:
[root@hyc-01-01 ~]# b=(1 2 3)
打印數組:
[root@hyc-01-01 ~]# echo ${b[@]}
1 2 3
[root@hyc-01-01 ~]# echo ${b[*]}
1 2 3
查看數組中某個元素的值:
[root@hyc-01-01 ~]# echo ${b[0]}
1
[root@hyc-01-01 ~]# echo ${b[1]}
2
[root@hyc-01-01 ~]# echo ${b[2]}
3
數組中元素的下標從0開始,分別爲第0個元素、第1個元素、第2個元素
獲取數組中元素的個數:
[root@hyc-01-01 ~]# echo ${#b[*]}
3
[root@hyc-01-01 ~]# echo ${#b[@]}
3
給數組重新賦值:
[root@hyc-01-01 ~]# b[3]=a
[root@hyc-01-01 ~]# echo ${#b[@]}
4
[root@hyc-01-01 ~]# echo ${b[@]}
1 2 3 a
覆蓋數組中原來的元素:
[root@hyc-01-01 ~]# b[3]=aaa
[root@hyc-01-01 ~]# echo ${b[@]}
1 2 3 aaa
刪除元素:
[root@hyc-01-01 ~]# echo ${b[@]}
1 2 3 aaa
[root@hyc-01-01 ~]# unset b[3] 刪除下標爲3的元素
[root@hyc-01-01 ~]# echo ${b[@]}
1 2 3
[root@hyc-01-01 ~]# unset b 刪除整個數組b
[root@hyc-01-01 ~]# echo ${b[@]}
截取部分數組:
[root@hyc-01-01 ~]# a=(`seq 1 10`)
[root@hyc-01-01 ~]# echo ${a[*]}
1 2 3 4 5 6 7 8 9 10
[root@hyc-01-01 ~]# echo ${a[@]:3:4} 從下標爲3的元素開始截取,截取4個元素
4 5 6 7
[root@hyc-01-01 ~]# echo ${a[@]:0-3:2} 從倒數第3個元素開始截取2個
8 9
數組替換:
[root@hyc-01-01 ~]# echo ${a[@]/8/6}
1 2 3 4 5 6 7 6 9 10
將數組a中的元素8替換爲6
[root@hyc-01-01 ~]# a=(${a[@]/8/6})
[root@hyc-01-01 ~]# echo ${a[@]}
1 2 3 4 5 6 7 6 9 10
20.19 告警系統需求分析
Shell項目
項目:告警系統
需求:
監控需求:
1 當監控項比較冷門,zabbix等監控工具中不包含該監控項時,需要用戶自定義監控腳本
2 C/S架構中服務器與客戶端網絡出現問題,無法將監控數據上報服務端,可以編寫用於監控的shell腳本,此時監控系統是分佈式的,用戶需要在每一臺被監控的機器上編輯shell腳本,每一臺機器都可以做到獨立監控,不需要依賴其他機器
告警需求:
當服務器多或告警頻繁時,假如每分鐘檢測一次,若每分鐘都出問題,那麼每分鐘都會發出較多郵件,所以需要做告警收斂
指定一個包含主程序、子程序、配置文件、郵件引擎、輸出日誌等的腳本包
腳本包中包含:
主程序:是整個腳本的入口,整個系統的命脈
配置文件:一個監控中心,用於開關 各個子程序,指定各個關聯的日誌文件
子程序:真正的監控腳本,用於監控各種指標
郵件引擎:用一個python程序實現,可以定義發郵件服務器、發郵件人、發件人密碼
輸出日誌:整個監控系統的日誌輸出
要求:
機器角色多樣,但所有機器都要部署同樣的監控系統;
無論機器角色,整個程序框架都是一致的;
根據機器角色不同,定製不同的配置文件
主目錄(mon):
bin
main.sh 主腳本
conf
mon.conf 配置文件
shares
load.sh 502.sh 監控子腳本
mail.py mail.sh 郵件
log
mon.log err.log 記錄日誌