【Shell脚本】shell获取某个进程运行时内存信息模板(monitor.sh)

本文详细解读了getopts命令行参数处理的机制,包括其内部变量的作用,非法处理方式,以及非静默模式的使用。并通过一个获取内存信息的函数实例,展示了如何在实际应用中灵活运用getopts。此外,文章还介绍了如何通过循环和数组比较,高效地获取和打印对应进程的信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

procNameArray="Host Superexe ServiceManager libplugin-container.so"
procName=""
ProcIdArray=0
ProcId=0
elastosMemmory=0
rate=5


#getopts 是用来处理命令行参数,一般的格式:getopts option varible
#getopts 使用的时候会自动产生两个变量OPTIND和OPTARGR,含义如下
#OPTIND:下一个待处理的参数索引,所以它的初始值就为1,从命令行参数开始,
#命令本身索引是0

#OPTARGR:获取期望参数后,把后面的内容存入OPTARGR中,例如输入
#monitor -d seconds -n proName后,第一次循环,会获取到参数1,即参数d(getopts
#会通过'-'来识别参数),这时就会把参数d后面跟的参数具体值存入到OPTARGR中。这里
#有一个地方大家会注意到 getopts d:n: opt,d和n后面都有一个冒号,这冒号表示在执行
#时,d的后面必须跟参数值的内容。

#getopts 具体的执行流程是每次都会获取到一个参数类型,然后和option比较,如果
#option中有,就把它放入opt变量中,没有把?放入opt变量中,同时把参数后面跟的内容
#放入OPTARGR。这里有一个顺序,是先和option比较,再放入opt中。

#介绍下getopts中的静默模式
#如果在option参数前加':',比如getopts :d:n: opt,这时针对d参数就会有两种非法处理
#方式,invalid option 和 miss option argument
#invalid option:就是当没有匹配上option时,就往变量opt中写入'?'
#miss option argument:当有匹配,但后面没有跟具体内容时,就往opt中写入':'

#非静默模式

 

#不管匹配还是没有内容,都往opt中写入'?'

 

 

while getopts d:n: opt
do
    case $opt in
        d )
            rate=$OPTARG
        ;;
        n )
            procNameArray=$OPTARG
        ;;
        ? )
            echo "usage :monitor -d seconds -n procName"
            break
        ;;
        esac
done

#"&&"的用法:至于"&&"左边的命令为真时,才会去执行右边的命令,所以在下面

#的判断中会发现continue的前面还有一个"&&",说明只有前面的命令全为真的时候

#才会执行continue(跳过本次循环的剩余代码,继续下一次循环)

getProcInfo() {
    #memory
    #VmPeak:    表示进程所占用最大虚拟内存大小
    #VmSize:    表示进程当前虚拟内存大小
    #VmLck:     表示被锁定的内存大小
    #VmHWM:     表示进程所占用物理内存的峰值
    #VmRSS:     表示进程当前占用物理内存的大小(与procrank中的RSS)
    #VmData:    表示进程数据段的大小
    #VmStk:     表示进程堆栈段的大小
    #VmExe:     表示进程代码的大小
    #VmLib:     表示进程所使用共享库的大小
    #VmPTE:     表示进程页表项的大小
    while read line
    do
        [[ "${line/"VmHWM:"/}" != "$line" ]] && info=${info}" "${line} && continue
        #[[ "${line/"VmRSS:"/}" != "$line" ]] && info=${info}" "${line} && continue
        [[ "${line/"Threads:"/}" != "$line" ]] && info=${info}" "${line} && continue
    #这里是将标准输入重定向到status文件,这是status作为标准输入,所以这里每次
    #都会从status文件中读取一行到line中,进行判断,一直读到文件结尾结束。
    #(注意,这里的重定向周期就是整个循环)
    done <"/proc/"$ProcId"/status"

    #procrank
    #VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
    #RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)
    #PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
    #USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
    #PID      Vss      Rss      Pss      Uss  cmdline
    #get PSS from procrank
    #procmem值得获取流程
    #1.通过adb shell procrank命令获取android中进程的内存信息
    #2.使用grep抓取对应ID的进程信息行,再通过awk命令获取信息行中第四个参数的值
    #3.使用sed对获取到的参数值进行处理,清除 非数字,',','.'字符,相应位置用
    #空格替换。sed 's/A/B/g'表示把A全部替换成B,B没有的时候,就替换成空格。
    procmem=`procrank | grep $ProcId | awk '{print $4}' | sed 's/[^0-9,. ]//g'`
    let "elastosMemmory = $elastosMemmory + $procmem"

    #openfile
    file="/proc/"$ProcId"/fd/"

    echo $ProcId $info  "OpenFile:"`ls $file | wc -l` "PSS:"$procmem"KB"
    info=""
}

 

下面是一个获取内存信息的函数

 

先来说一下${line:0:8}的意思:该命令就是获取当前行从0到8的字符,然后判断是不是和后面提供的字符串一样,例如"MemFree:"。

${line:0:8}的模式定义是${var:position:length} -- var表示变量;position表示开始位置;length表示要提取子串的长度。

 

 

getFreeMemory() {
    while read line
    do
        [[ "${line:0:8}" == "MemFree:" ]] && memfree=`echo $line | sed 's/[^0-9,. ]//g'` && continue
        [[ "${line:0:8}" == "Buffers:" ]] && buffers=`echo $line | sed 's/[^0-9,. ]//g'` && continue
        [[ "${line:0:7}" == "Cached:" ]] && cached=`echo $line | sed 's/[^0-9,. ]//g'` && break
    done <"/proc/meminfo"

    let "totalFree = $memfree + $buffers + $cached"
    echo "TotalFree:"$totalFree"kB"
}

 

#循环获取对应进程的信息
while true; do
    #用procName循环和procNameArray数组比较,看是否有对应的进程
    for procName in ${procNameArray[@]}     
    do
        echo ""
        getProcId   #获取对应的ID

        for ProcId in ${ProcIdArray[@]}
        do
            getProcInfo #打印对应ID的信息
        done
    done

    echo "Elastos Memory: "$elastosMemmory"KB"
    elastosMemmory=0
    getFreeMemory

    let "count = $count + 1"
    echo $count
    echo "----------------------------------\n"
    sleep $rate #沉睡多少秒后再循环
done


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值