简单进程监控程序
簡單進(jìn)程監(jiān)控程序
文章目錄
- 簡單進(jìn)程監(jiān)控程序
- 題目描述
- 解題思路
- 詳細(xì)編碼實現(xiàn)
- 1.判斷進(jìn)程
- 2.檢查文件
- 3.處理注釋
- 4.函數(shù)封裝
- 5.整體代碼
- 運行腳本
- 參考文章
題目描述
作業(yè)題目:寫一個 Shell 腳本來進(jìn)行進(jìn)程的死活監(jiān)控
作業(yè)描述:此 Shell 腳本能檢查配置文件中記錄的進(jìn)程是否在系統(tǒng)中運行。如果在系統(tǒng)中運行則顯示進(jìn)程ID(PID),如果不在運行則顯示 DOWN 文字。
配置文件(check_procs.conf):
systemd smbd nmbd #logd sshd腳本命名為check_proc.sh, 執(zhí)行腳本后的輸出結(jié)果:
systemd: 1 5241 31842 smbd: DOWN nmbd: DOWN sshd: 5025 31840 31857要求:
- 考慮各種錯誤場景的出錯處理
- 關(guān)鍵代碼要有合理注釋
- 進(jìn)行合理的函數(shù)功能封裝
解題思路
題目的意圖很明顯,就是讓我們讀入配置文件,然后挨個判斷文件中記錄的進(jìn)程是否在系統(tǒng)中運行,運行則給出 PID,否則顯示 DOWN。根據(jù)輸入和輸出結(jié)果可以看出,注釋掉的進(jìn)程是不用判斷的,直接略過。
核心的功能就是三步,讀取文件、跳過注釋、判斷進(jìn)程,最后將功能合理封裝為函數(shù)運行即可。
詳細(xì)編碼實現(xiàn)
在編寫代碼之前,有一個非常重要的注意事項,Shell中的變量賦值是不能有空格的。比如我們要將給變量 a 賦值為5,應(yīng)該寫為 a=5,而不能是 a = 5。雖然加了空格會更美觀,但是代碼就不能按照預(yù)期運行了,所以賦值等號兩邊一定不要加空格!
1.判斷進(jìn)程
判斷進(jìn)程是程序最核心的功能,我們可以先進(jìn)行進(jìn)程判斷,再將其他的功能加上。
使用非常典型的通過 grep 獲取進(jìn)程ID的方法,判斷systemd 這個進(jìn)程是否在運行。
program="systemd" # 進(jìn)程名稱#獲取進(jìn)程PID,為空則進(jìn)程未啟動 pid=`ps -ef | grep $program | grep -v grep |awk '{print $2}'` if [ "${pid}" == "" ] thenecho "${program}: DOWN" elseecho -ne "${program}: " # echo默認(rèn)換行,-ne表示當(dāng)前輸出不換行echo ${pid} fi- ps -ef ,顯示所有的進(jìn)程,e顯示結(jié)果,f 顯示完整格式
- ps -ef | grep xxx ,把包括 xxx 這個關(guān)鍵字的進(jìn)程都顯示出來
- grep -v grep,去除 grep 進(jìn)程(即去除含有 xxx 關(guān)鍵字的這個grep查找進(jìn)程本身)
- awk ‘{print $2}’,提取結(jié)果的第二列數(shù)據(jù)(因為第二列正是進(jìn)程的PID)
2.檢查文件
方便起見,我們就將文件放在 shell 腳本的同級目錄下。新建配置文件 check_procs.conf,將上面的配置文件示例全部寫入
在腳本中編寫判斷文件是否存在的代碼
fileName="check_procs.conf" # 文件名 BASE_PATH=$(cd `dirname $0`; pwd) # 獲取當(dāng)前目錄if [ ! -e "${BASE_PATH}/${fileName}" ] # 判斷當(dāng)前目錄下文件是否存在 thenecho "文件不存在或無法讀取"exit 0 fi- dirname $0,取得當(dāng)前執(zhí)行的腳本文件的父目錄
- cd ‘dirname $0’, 進(jìn)入這個目錄(切換當(dāng)前工作目錄)
- pwd,顯示當(dāng)前工作目錄(cd執(zhí)行后的)
3.處理注釋
讀取文件,按每一行進(jìn)行判斷,line為變量,表示每一行的內(nèi)容
判斷當(dāng)前行第一個字符是否為 #,如果是則當(dāng)前行全部是注釋,忽略即可
cat $fileName | while read line # 讀取文件,按行處理 doif [ "${line:0:1}" == "#" ] # 第一個字符為 ‘#’then# 此處編寫處理語句fi done可以看到,當(dāng)前這個注釋判斷十分簡單,僅僅是將第一個字符為 # 的內(nèi)容全部忽略
對于 ”注釋在行內(nèi)“ 、”多行注釋“ 等這樣的內(nèi)容是不能判斷的,還有待學(xué)習(xí)優(yōu)化。
4.函數(shù)封裝
Shell 中用戶自定義的函數(shù)不需要像 C 一樣指明類型,函數(shù)返回值可以用 return 來返回, return后跟一個數(shù)值,范圍為 0-255。如果不用 return,將以最后一條命令運行結(jié)果作為返回值。
-
調(diào)用函數(shù)時可以向其傳遞參數(shù),在函數(shù)內(nèi)部使用 $n 的形式來獲取參數(shù)的值。比如 $1表示第一個參數(shù),$2表示第二個參數(shù),當(dāng)n>=10時,需要使用 ${n} 來獲取參數(shù),比如第十個參數(shù) ${10}。
-
函數(shù)返回值在調(diào)用該函數(shù)后通過 $? 來獲得。但是$? 僅對其上一條指令負(fù)責(zé),一旦函數(shù)返回后其返回值沒有立即保存入?yún)?shù),那么其返回值將不再能通過 $? 獲得,所以函數(shù)返回值必須第一時間使用或保存。
有一點要注意的是,所有函數(shù)在使用前必須定義。所以說,應(yīng)該將自定義函數(shù)放在腳本的開頭部分,這樣函數(shù)就可以正常使用了。
fileName="check_prog.conf" program="" # program為變量,用來接收參數(shù)# 讀取文件 getFile(){BASE_PATH=$(cd `dirname $0`; pwd)if [ ! -e "${BASE_PATH}/${fileName}" ]thenecho "文件不存在或無法讀取"exit 0fi } # 跳過注釋 crossNote(){program=$1 # 接收傳遞的參數(shù)if [ "${program:0:1}" == "#" ]thenreturn 1 # 當(dāng)前行為注釋,返回1fi } # 判斷進(jìn)程 judgeProgress(){program=$1 # 接收傳遞的參數(shù)pid=`ps -ef | grep $program | grep -v grep |awk '{print $2}'`if [ "${pid}" == "" ]thenecho "${program}: DOWN"elseecho -ne "${program}: "echo ${pid}fi }編寫主函數(shù),首先讀取文件,然后每行都直接去掉注釋,再判斷進(jìn)程是否在運行。
# 主函數(shù) main(){ getFile fileName # 判斷文件存在 cat $fileName | while read line # 按行讀取文件 docrossNote $line # 每一行判斷注釋if [ $? == 1 ] # 返回值為1,當(dāng)前行為注釋,忽略thencontinuefijudgeProgress $line # 判斷進(jìn)程是否運行 done } main5.整體代碼
#! /bin/bash # 用于實現(xiàn)進(jìn)程監(jiān)控的shell腳本 fileName="check_procs.conf" program=""# 讀取文件 getFile(){BASE_PATH=$(cd `dirname $0`; pwd)if [ ! -e "${BASE_PATH}/${fileName}" ]thenecho "文件不存在或無法讀取"exit 0fi } # 跳過注釋 crossNote(){program=$1if [ "${program:0:1}" == "#" ]thenreturn 1fi } # 判斷進(jìn)程 judgeProgress(){program=$1#獲得進(jìn)程PID,為空則進(jìn)程未啟動pid=`ps -ef | grep $program | grep -v grep |awk '{print $2}'`if [ "${pid}" == "" ]thenecho "${program}: DOWN"elseecho -ne "${program}: "echo ${pid}fi }# 主函數(shù) main(){ getFile fileName cat $fileName | while read line docrossNote $lineif [ $? == 1 ]thencontinuefijudgeProgress $line done } main運行腳本
如果在運行腳本時遇到了錯誤,請參考這篇文章進(jìn)行解決 Shell腳本使用常見問題說明
我們在當(dāng)前目錄下輸入 ll 命令,確認(rèn)配置文件已經(jīng)存在
然后在終端中輸入運行腳本的命令
./check_proc.sh回車即可看到最終的運行結(jié)果
參考文章
Linux常用命令
vim編輯器的常用技巧
Shell腳本使用常見問題說明
Shell 函數(shù)
kill -9 ps -ef|grep cpu|grep -v grep|awk '{print $2}'命令解析
總結(jié)
- 上一篇: Shell脚本使用常见问题说明
- 下一篇: Win10安装Latex