使用 shell 腳本對 Linux 系統和進程資源進行監控

Shell 簡介

Shell 語言對於接觸 LINUX 的人來說都比較熟悉,它是系統的用戶界面,提供了用戶與內核進行交互操作的一種接口。它接收用戶輸入的命令並把它送入內核去執行。實際上 Shell 是一個命令解釋器,它解釋由用戶輸入的命令並且把它們送到內核。它沒有一般編程語言的“編譯 - 鏈接 - 運行”過程。不僅如此,Shell 有自己的編程語言用於對命令的編輯,它允許用戶編寫由 shell 命令組成的程序。Shell 編程語言具有普通編程語言的很多特點,比如它也有循環結構和分支控制結構等,用這種編程語言編寫的 Shell 程序與其他應用程序具有同樣的效果。當然,Shell 功能也是很強大的。Shell 有多種類型,其中最常用的幾種是 Bourne shell(sh)、C shell(csh)和 Korn shell(ksh)。三種 shell 各有優缺點,Linux 操作系統缺省的 shell 一般是 Bourne Again shell,它是 Bourne shell 的擴展,簡稱 Bash,bash 的命令語法是 Bourne shell 命令語法的超集,並且在 Bourne shell 的基礎上增加、增強了很多特性。在這裏,我們以 Bash 做爲實例總結了使用 Shell 對系統和進程資源進行監控的一些內容,希望對您能有幫助。

使用 Shell 對進程資源進行監控

檢查進程是否存在

在對進程進行監控時,我們一般需要得到該進程的 ID,進程 ID 是進程的唯一標識,但是有時可能在服務器上不同用戶下運行着多個相同進程名的進程,下面的函數 GetPID 給出了獲取指定用戶下指定進程名的進程 ID 功能(目前只考慮這個用戶下啓動一個此進程名的進程),它有兩個參數爲用戶名和進程名,它首先使用 ps 查找進程信息,同時通過 grep 過濾出需要的進程,最後通過 sed 和 awk 查找需要進程的 ID 值(此函數可根據實際情況修改,比如需要過濾其它信息等)。


清單 1. 對進程進行監控
				
 function GetPID #User #Name 
 { 
    PsUser=$1 
    PsName=$2 
    pid=`ps -u $PsUser|grep $PsName|grep -v grep|grep -v vi|grep -v dbx\n 
    |grep -v tail|grep -v start|grep -v stop |sed -n 1p |awk '{print $1}'` 
    echo $pid 
 } 

示例演示:

1)源程序(例如查找用戶爲 root,進程名爲 CFTestApp 的進程 ID)

    PID=`GetPID root CFTestApp` 
 
    echo $PID 

2)結果輸出

    11426 
    [dyu@xilinuxbldsrv shell]$ 

3)結果分析

從上面的輸出可見:11426 爲 root 用戶下的 CFTestApp 程序的進程 ID。

4)命令介紹

1. ps: 查看系統中瞬間進程信息。
參數:-u< 用戶識別碼 > 列出屬於該用戶的程序的狀況,也可使用用戶名稱來指定。
-p< 進程識別碼 > 指定進程識別碼,並列出該進程的狀況。
-o 指定輸出格式
2. grep: 用於查找文件中符合字符串的當前行。
參數:-v 反向選擇,亦即顯示出沒有 '搜尋字符串' 內容的那一行。
3. sed: 一個非交互性文本編輯器,它編輯文件或標準輸入導出的文件,一次只能處理一行內容。
參數:-n 讀取下一個輸入行,用下一個命令處理新的行而不是用第一個命令。
p 標誌 打印匹配行
4. awk:一種編程語言,用於在 linux/unix 下對文本和數據進行處理。數據可以來自標準輸入、一個或多個文件,或其它命令的輸出。它支持用戶自定義函數和動態正則表達式等先進功能,是 linux/unix 下的一個強大編程工具。它在命令行中使用,但更多是作爲腳本來使用。awk 的處理文本和數據的方式:它逐行掃描文件,從第一行到最後一行,尋找匹配的特定模式的行,並在這些行上進行你想要的操作。如果沒有指定處理動作,則把匹配的行顯示到標準輸出 ( 屏幕 ),如果沒有指定模式,則所有被操作所指定的行都被處理。
參數:-F fs or --field-separator fs :指定輸入文件折分隔符,fs 是一個字符串或者是一個正則表達式,如 -F:。


有時有可能進程沒有啓動,下面的功能是檢查進程 ID 是否存在,如果此進程沒有運行輸出:

    The process does not exist. 
    # 檢查進程是否存在
    if [ "-$PID" == "-" ] 
    then 
    { 
        echo "The process does not exist."
    } 
    fi 

檢測進程 CPU 利用率

在對應用服務進行維護時,我們經常遇到由於 CPU 過高導致業務阻塞,造成業務中斷的情況。CPU 過高可能由於業務量過負荷或者出現死循環等異常情況,通過腳本對業務進程 CPU 進行時時監控,可以在 CPU 利用率異常時及時通知維護人員,便於維護人員及時分析,定位,以及避免業務中斷等。下面的函數可獲得指定進程 ID 的進程 CPU 利用率。它有一個參數爲進程 ID,它首先使用 ps 查找進程信息,同時通過 grep -v 過濾掉 %CPU 行,最後通過 awk 查找 CPU 利用百分比的整數部分(如果系統中有多個 CPU,CPU 利用率可以超過 100%)。


清單 2. 對業務進程 CPU 進行實時監控
				
function GetCpu 
  { 
   CpuValue=`ps -p $1 -o pcpu |grep -v CPU | awk '{print $1}' | awk -  F. '{print $1}'` 
        echo $CpuValue 
    } 

下面的功能是通過上面的函數 GetCpu 獲得此進程的 CPU 利用率,然後通過條件語句判斷 CPU 利用率是否超過限制,如果超過 80%(可以根據實際情況進行調整),則輸出告警,否則輸出正常信息。


清單 3. 判斷 CPU 利用率是否超過限制
				
 function CheckCpu 
 { 
    PID=$1 
    cpu=`GetCpu $PID` 
    if [ $cpu -gt 80 ] 
    then 
    { 
 echo “The usage of cpu is larger than 80%”
    } 
    else 
    { 
 echo “The usage of cpu is normal”
    } 
    fi 
 } 

示例演示:

1)源程序(假設上面已經查詢出 CFTestApp 的進程 ID 爲 11426)

 CheckCpu 11426 

2)結果輸出

    The usage of cpu is 75 
    The usage of cpu is normal 
    [dyu@xilinuxbldsrv shell]$ 

3)結果分析

從上面的輸出可見:CFTestApp 程序當前的 CPU 使用爲 75%,是正常的,沒有超過 80% 的告警限制。

檢測進程內存使用量

在對應用服務進行維護時,也經常遇到由於內存使用過大導致進程崩潰,造成業務中斷的情況(例如 32 位程序可尋址的最大內存空間爲 4G,如果超出將申請內存失敗,同時物理內存也是有限的)。內存使用過高可能由於內存泄露,消息堆積等情況,通過腳本對業務進程內存使用量進行時時監控,可以在內存使用量異常時及時發送告警(例如通過短信),便於維護人員及時處理。下面的函數可獲得指定進程 ID 的進程內存使用情況。它有一個參數爲進程 ID,它首先使用 ps 查找進程信息,同時通過 grep -v 過濾掉 VSZ 行 , 然後通過除 1000 取以兆爲單位的內存使用量。


清單 4. 對業務進程內存使用量進行監控
				
    function GetMem 
    { 
        MEMUsage=`ps -o vsz -p $1|grep -v VSZ` 
        (( MEMUsage /= 1000)) 
        echo $MEMUsage 
    } 

下面的功能是通過上面的函數 GetMem獲得此進程的內存使用,然後通過條件語句判斷內存使用是否超過限制,如果超過 1.6G(可以根據實際情況進行調整),則輸出告警,否則輸出正常信息。


清單 5. 判斷內存使用是否超過限制
				
 mem=`GetMem $PID`                
 if [ $mem -gt 1600 ] 
 then 
 { 
     echo “The usage of memory is larger than 1.6G”
 } 
 else 
 { 
    echo “The usage of memory is normal”
 } 
 fi 

示例演示:

1)源程序(假設上面已經查詢出 CFTestApp 的進程 ID 爲 11426)

    mem=`GetMem 11426` 

    echo "The usage of memory is $mem M"

    if [ $mem -gt 1600 ] 
    then 
    { 
         echo "The usage of memory is larger than 1.6G"
    } 
    else 
    { 
        echo "The usage of memory is normal"
    } 
    fi  

2)結果輸出

    The usage of memory is 248 M 
    The usage of memory is normal 
    [dyu@xilinuxbldsrv shell]$ 

3)結果分析

從上面的輸出可見:CFTestApp 程序當前的內存使用爲 248M,是正常的,沒有超過 1.6G 的告警限制。

檢測進程句柄使用量

在對應用服務進行維護時,也經常遇到由於句柄使用 過量導致業務中斷的情況。每個平臺對進程的句柄使用都是有限的,例如在 Linux 平臺,我們可以使用 ulimit – n 命令(open files (-n) 1024)或者對 /etc/security/limits.conf 的內容進行查看,得到進程句柄限制。句柄使用過高可能由於負載過高,句柄泄露等情況,通過腳本對業務進程句柄使用量進行時時監控,可以在異常時及時發送告警(例如通過短信),便於維護人員及時處理。下面的函數可獲得指定進程 ID 的進程句柄使用情況。它有一個參數爲進程 ID,它首先使用 ls 輸出進程句柄信息,然後通過 wc -l 統計輸出句柄個數。

    function GetDes 
    { 
        DES=`ls /proc/$1/fd | wc -l` 
        echo $DES 
    } 

下面功能是通過上面的函數 GetDes獲得此進程的句柄使用量,然後通過條件語句判斷句柄使用是否超過限制,如果超過 900(可以根據實際情況進行調整)個,則輸出告警,否則輸出正常信息。

 des=` GetDes $PID` 
 if [ $des -gt 900 ] 
 then 
 { 
     echo “The number of des is larger than 900”
 } 
 else 
 { 
    echo “The number of des is normal”
 } 
 fi 

示例演示:

1)源程序(假設上面查詢出 CFTestApp 的進程 ID 爲 11426)

    des=`GetDes 11426` 

    echo "The number of des is $des"

    if [ $des -gt 900 ] 
    then 
    { 
         echo "The number of des is larger than 900"
    } 
    else 
    { 
        echo "The number of des is normal"
    } 
    fi  

2)結果輸出

    The number of des is 528 
    The number of des is normal 
    [dyu@xilinuxbldsrv shell]$ 

3)結果分析

從上面的輸出可見:CFTestApp 程序當前的句柄使用爲 528 個,是正常的,沒有超過 900 個的告警限制。

4)命令介紹

wc: 統計指定文件中的字節數、字數、行數 , 並將統計結果顯示輸出。
參數:-l 統計行數。
-c 統計字節數。
-w 統計字數。


使用 Shell 對系統資源進行監控

查看某個 TCP 或 UDP 端口是否在監聽

端口檢測是系統資源檢測經常遇到的,特別是在網絡通訊情況下,端口狀態的檢測往往是很重要的。有時可能進程,CPU,內存等處於正常狀態,但是端口處於異常狀態,業務也是沒有正常運行。下面函數可判斷指定端口是否在監聽。它有一個參數爲待檢測端口,它首先使用 netstat 輸出端口占用信息,然後通過 grep, awk,wc 過濾輸出監聽 TCP 端口的個數,第二條語句爲輸出 UDP 端口的監聽個數,如果 TCP 與 UDP 端口監聽都爲 0,返回 0,否則返回 1.


清單 6. 端口檢測
				
 function Listening 
 { 
    TCPListeningnum=`netstat -an | grep ":$1 " | \n
    awk '$1 == "tcp" && $NF == "LISTEN" {print $0}' | wc -l` 
    UDPListeningnum=`netstat -an|grep ":$1 " \n
    |awk '$1 == "udp" && $NF == "0.0.0.0:*" {print $0}' | wc -l` 
    (( Listeningnum = TCPListeningnum + UDPListeningnum )) 
    if [ $Listeningnum == 0 ] 
    then 
    { 
        echo "0"
    } 
    else 
    { 
       echo "1"
    } 
    fi 
 } 

示例演示:

1)源程序(例如查詢 8080 端口的狀態是否在監聽)

    isListen=`Listening 8080` 
    if [ $isListen -eq 1 ] 
    then 
    { 
        echo "The port is listening"
    } 
    else 
    { 
        echo "The port is not listening"
    } 
    fi 

2)結果輸出

    The port is listening 
    [dyu@xilinuxbldsrv shell]$ 

3)結果分析

從上面的輸出可見:這個 Linux 服務器的 8080 端口處在監聽狀態。

4)命令介紹

netstat: 用於顯示與 IP、TCP、UDP 和 ICMP 協議相關的統計數據,一般用於檢驗本機各端口的網絡連接情況。
參數:-a 顯示所有連線中的 Socket。
-n 直接使用 IP 地址,而不通過域名服務器。

下面的功能也是檢測某個 TCP 或者 UDP 端口是否處在正常狀態。

 tcp: netstat -an|egrep $1 |awk '$6 == "LISTEN" && $1 == "tcp" {print $0}'
 udp: netstat -an|egrep $1 |awk '$1 == "udp" && $5 == "0.0.0.0:*" {print $0}'

命令介紹

egrep: 在文件內查找指定的字符串。egrep 執行效果如 grep -E,使用的語法及參數可參照 grep 指令,與 grep 不同點在於解讀字符串的方法,egrep 是用擴展的正則表達式語法來解讀,而 grep 則用基本的正則表達式語法,擴展的正則表達式比基本的正則表達式有更完整的表達規範。

查看某個進程名正在運行的個數

有時我們可能需要得到服務器上某個進程的啓動個數,下面的功能是檢測某個進程正在運行的個數,例如進程名爲 CFTestApp。

 Runnum=`ps -ef | grep -v vi | grep -v tail | grep "[ /]CFTestApp" | grep -v grep | wc -l

檢測系統 CPU 負載

在對服務器進行維護時,有時也遇到由於系統 CPU(利用率)負載 過量導致業務中斷的情況。服務器上可能運行多個進程,查看單個進程的 CPU 都是正常的,但是整個系統的 CPU 負載可能是異常的。通過腳本對系統 CPU 負載進行時時監控,可以在異常時及時發送告警,便於維護人員及時處理,預防事故發生。下面的函數可以檢測系統 CPU 使用情況 . 使用 vmstat 取 5 次系統 CPU 的 idle 值,取平均值,然後通過與 100 取差得到當前 CPU 的實際佔用值。

 function GetSysCPU 
 { 
   CpuIdle=`vmstat 1 5 |sed -n '3,$p' \n
   |awk '{x = x + $15} END {print x/5}' |awk -F. '{print $1}'
   CpuNum=`echo "100-$CpuIdle" | bc` 
   echo $CpuNum 
 } 

示例演示:

1)源程序

 cpu=`GetSysCPU` 

 echo "The system CPU is $cpu"

 if [ $cpu -gt 90 ] 
 then 
 { 
    echo "The usage of system cpu is larger than 90%"
 } 
 else 
 { 
    echo "The usage of system cpu is normal"
 } 
 fi 

2)結果輸出

 The system CPU is 87 
 The usage of system cpu is normal 
 [dyu@xilinuxbldsrv shell]$ 

3)結果分析

從上面的輸出可見:當前 Linux 服務器系統 CPU 利用率爲 87%,是正常的,沒有超過 90% 的告警限制。

4)命令介紹

vmstat:Virtual Meomory Statistics(虛擬內存統計)的縮寫,可對操作系統的虛擬內存、進程、CPU 活動進行監視。
參數: -n 表示在週期性循環輸出時,輸出的頭部信息僅顯示一次。

檢測系統磁盤空間

系統磁盤空間檢測是系統資源檢測的重要部分,在系統維護維護中,我們經常需要查看服務器磁盤空間使用情況。因爲有些業務要時時寫話單,日誌,或者臨時文件等,如果磁盤空間用盡,也可能會導致業務中斷,下面的函數可以檢測當前系統磁盤空間中某個目錄的磁盤空間使用情況 . 輸入參數爲需要檢測的目錄名,使用 df 輸出系統磁盤空間使用信息,然後通過 grep 和 awk 過濾得到某個目錄的磁盤空間使用百分比。

 function GetDiskSpc 
 { 
    if [ $# -ne 1 ] 
    then 
        return 1 
    fi 

    Folder="$1$"
    DiskSpace=`df -k |grep $Folder |awk '{print $5}' |awk -F% '{print $1}'
    echo $DiskSpace 
 } 

示例演示:

1)源程序(檢測目錄爲 /boot)

 Folder="/boot"

 DiskSpace=`GetDiskSpc $Folder` 

 echo "The system $Folder disk space is $DiskSpace%"

 if [ $DiskSpace -gt 90 ] 
 then 
 { 
    echo "The usage of system disk($Folder) is larger than 90%"
 } 
 else 
 { 
    echo "The usage of system disk($Folder)  is normal"
 } 
 fi  

2)結果輸出

 The system /boot disk space is 14% 
 The usage of system disk(/boot)  is normal 
 [dyu@xilinuxbldsrv shell]$ 

3)結果分析

從上面的輸出可見:當前此 Linux 服務器系統上 /boot 目錄的磁盤空間已經使用了 14%,是正常的,沒有超過使用 90% 的告警限制。

4)命令介紹

df:檢查文件系統的磁盤空間佔用情況。可以利用該命令來獲取硬盤被佔用了多少空間,目前還剩下多少空間等信息。
參數:-k 以 k 字節爲單位顯示。

在 Linux 平臺下,shell 腳本監控是一個非常簡單,方便,有效的對服務器,進程進行監控的方法,對系統開發以及進程維護人員非常有幫助。它不僅可以對上面的信息進行監控,發送告警,同時也可以監控進程的日誌等等的信息,希望本文對大家有幫助。

發佈了33 篇原創文章 · 獲贊 1 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章