首先,我是新手。我有一些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语句中替换echos,但无论cpu负载实际是什么,它都表现得好像(我通过更改-gt测试了这一点) to -lt它仍然回应着#crap"
感谢您的帮助。哦,如果这很重要,那就是OS X 10.7。
答案 0 :(得分: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%,即使它们正在捣乱。
答案 1 :(得分:7)
我建议您查看ps
的设施,以避免发生多种可怕的事情。
在我的系统上(ps
来自procps on linux,GNU awk)我会这样做:
ps -C "$app-name" -o pid=,pcpu= |
awk --assign maxcpu="$cpu_limit" '$2>maxcpu {print "crappy pid",$1}'
答案 2 :(得分:2)
#!/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
答案 3 :(得分:0)
我使用top
检查一些细节。它提供了更多细节,如cpu time。
top -l 1 | grep $app_name
答案 4 :(得分:0)
我想出了这个,使用top和bc。
通过传递ex:./script apache2 50 # max 50%
如果有许多PID与您的程序参数匹配,则只会根据top列出它们的方式计算一个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 :(得分:0)
用于按进程获取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
答案 6 :(得分:0)
使用app_user
信息来测试当前用户是否有权终止/修改正在运行的进程也很有用。通过使用app_pid
消除对app_cpu
或任何其他第三方解析器的需求,可以与所需的read
和awk
一起获取此信息:
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))
注意:在defunct
中加入${0##*/}
和grep -v
可防止多个进程与$app_name
匹配。