使用 Shell 指令碼監控 Linux 系統程式資源

developerworks發表於2015-03-03

本文主要介紹 Linux 平臺下的 shell 指令碼使用,主要包括如何對系統和程式資源進行有效的監控。

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 指令碼監控是一個非常簡單,方便,有效的對伺服器,程式進行監控的方法,對系統開發以及程式維護人員非常有幫助。它不僅可以對上面的資訊進行監控,傳送告警,同時也可以監控程式的日誌等等的資訊,希望本文對大家有幫助。

相關文章