Bash脚本检查特定进程的cpu使用情况
Posted
技术标签:
【中文标题】Bash脚本检查特定进程的cpu使用情况【英文标题】:Bash script checking cpu usage of specific process 【发布时间】:2013-01-30 21:22:38 【问题描述】:首先,我是新手。我对 Windows 脚本和苹果脚本有一些经验,但对 bash 没有太多经验。我想要做的是获取特定进程的 PID 和 %CPU。然后将 %CPU 与设定的数字进行比较,如果更高,则终止该进程。我觉得我很接近了,但现在我收到以下错误:
[[: 0.0: 语法错误:算术运算符无效(错误标记为“.0”)
我做错了什么?到目前为止,这是我的代码:
#!/bin/bash
declare -i app_pid
declare -i app_cpu
declare -i cpu_limit
app_name="top"
cpu_limit="50"
app_pid=`ps aux | grep $app_name | grep -v grep | awk 'print $2'`
app_cpu=`ps aux | grep $app_name | grep -v grep | awk 'print $3'`
if [[ ! $app_cpu -gt $cpu_limit ]]; then
echo "crap"
else
echo "we're good"
fi
显然,我将替换 if/then 语句中的回声,但无论 CPU 负载实际是什么,它都表现得好像该语句是真的(我通过将 -gt 更改为 -lt 来测试它,但它仍然回响“废话”
感谢您的所有帮助。哦,如果这很重要的话,这是在 OS X 10.7 上。
【问题讨论】:
【参考方案1】:#!/bin/sh
PROCESS="java"
PID=`pgrep $PROCESS | tail -n 1`
CPU=`top -b -p $PID -n 1 | tail -n 1 | awk 'print $9'`
echo $CPU
【讨论】:
【参考方案2】:提供app_user
信息来测试当前用户是否有权杀死/修改正在运行的进程也很有用。可以使用read
获取此信息以及所需的app_pid
和app_cpu
,从而无需awk
或任何其他第3 方解析器:
read app_user app_pid tmp_cpu stuff <<< \
$( ps aux | grep "$app_name" | grep -v "grep\|defunct\|$0##*/" )
然后您可以通过以下方式获取您的app_cpu * 100
:
app_cpu=$(($tmp_cpu%.* * 100))
注意:在grep -v
中包含defunct
和$0##*/
可防止多个进程匹配$app_name
。
【讨论】:
【参考方案3】:Erik,我使用您的代码的修改版本创建了一个执行类似操作的新脚本。希望你不要介意。
按进程获取 CPU 使用率的 bash 脚本 用法:
nohup ./check_proc bwengine 70 &
bwegnine
是我们要监控的进程名称 70 是仅在进程使用超过 70% 的 CPU 时记录。
查看日志:/var/log/check_procs.log
输出应该是这样的:
DATE | TOTAL CPU | CPU USAGE | Process details
例子:
03/12/14 17:11 |20.99|98| ProdPROXY-ProdProxyPA.tra
03/12/14 17:11 |20.99|100| ProdPROXY-ProdProxyPA.tra
完整博客链接: http://felipeferreira.net/?p=1453
【讨论】:
【参考方案4】:我想出了这个,使用 top 和 bc。
通过传入 ex 来使用它:./script apache2 50 # max 50%
如果有许多 PID 与您的程序参数匹配,则只会根据顶部列出它们的方式计算一个。我可以通过捕获所有这些并平均百分比或其他东西来扩展脚本,但这必须这样做。
您也可以传入一个数字 ./script.sh 12345 50
,这将强制它使用精确的 PID。
#!/bin/bash
# 1: ['command\ name' or PID number(,s)] 2: MAX_CPU_PERCENT
[[ $# -ne 2 ]] && exit 1
PID_NAMES=$1
# get all PIDS as nn,nn,nn
if [[ ! "$PID_NAMES" =~ ^[0-9,]+$ ]] ; then
PIDS=$(pgrep -d ',' -x $PID_NAMES)
else
PIDS=$PID_NAMES
fi
# echo "$PIDS $MAX_CPU"
MAX_CPU="$2"
MAX_CPU="$(echo "($MAX_CPU+0.5)/1" | bc)"
LOOP=1
while [[ $LOOP -eq 1 ]] ; do
sleep 0.3s
# Depending on your 'top' version and OS you might have
# to change head and tail line-numbers
LINE="$(top -b -d 0 -n 1 -p $PIDS | head -n 8 \
| tail -n 1 | sed -r 's/[ ]+/,/g' | \
sed -r 's/^\,|\,$//')"
# If multiple processes in $PIDS, $LINE will only match\
# the most active process
CURR_PID=$(echo "$LINE" | cut -d ',' -f 1)
# calculate cpu limits
CURR_CPU_FLOAT=$(echo "$LINE"| cut -d ',' -f 9)
CURR_CPU=$(echo "($CURR_CPU_FLOAT+0.5)/1" | bc)
echo "PID $CURR_PID: $CURR_CPU""%"
if [[ $CURR_CPU -ge $MAX_CPU ]] ; then
echo "PID $CURR_PID ($PID_NAMES) went over $MAX_CPU""%"
echo "[[ $CURR_CPU""% -ge $MAX_CPU""% ]]"
LOOP=0
break
fi
done
echo "Stopped"
【讨论】:
【参考方案5】:我使用top
来检查一些细节。它提供了更多细节,例如 cpu 时间。
top -l 1 | grep $app_name
【讨论】:
【参考方案6】:我建议你看看ps
的设施,以避免你做很多可怕的事情。
在我的系统上(ps
来自 linux 上的 procps,GNU awk)我会这样做:
ps -C "$app-name" -o pid=,pcpu= |
awk --assign maxcpu="$cpu_limit" '$2>maxcpu print "crappy pid",$1'
【讨论】:
【参考方案7】:问题是 bash 不能处理小数。您可以将它们乘以 100,然后使用纯整数:
#!/bin/bash
declare -i app_pid
declare -i app_cpu
declare -i cpu_limit
app_name="top"
cpu_limit="5000"
app_pid=`ps aux | grep $app_name | grep -v grep | awk 'print $2'`
app_cpu=`ps aux | grep $app_name | grep -v grep | awk 'print $3*100'`
if [[ $app_cpu -gt $cpu_limit ]]; then
echo "crap"
else
echo "we're good"
fi
请记住,CPU 百分比是衡量应用程序运行状况的次优指标。如果您有两个进程在单核系统上运行无限循环,那么没有其他具有相同优先级的应用程序将永远超过 33%,即使它们正在乱扔垃圾。
【讨论】:
感谢大家的帮助!至于 %CPU,我们实际上有一个进程开始消耗 CPU,达到 100-200%,然后它会阻止用户登录计算机,杀死进程会导致它重新启动并长时间处于 0.1%时间。我计划将此作为“按需”启动守护程序运行,因此它应该终止该进程,因此用户不必在屏幕锁定时重新启动 1/3-1/2。 如果有多个同名进程,我只需要找到设置CPU之上的那个?./killJava.sh: line 7: 2941 8715: syntax error in expression (error token is "8715") ./killJava.sh: line 8: 10 60: syntax error in expression (error token is "60")
这些错误是什么?
@SandeepC 表示有多个进程,原脚本没有考虑到
要对列表中的每个项目执行某项操作,请使用循环以上是关于Bash脚本检查特定进程的cpu使用情况的主要内容,如果未能解决你的问题,请参考以下文章