[英]Capture %CPU and PID of processes filtered by COMMAND using top command
我需要编写一个执行以下操作的Bash脚本:
示例:假设有三个“chrome”进程,“logfile”中的输出应如下所示(前三秒):
17:49:12 7954 14.0
17:49:12 7969 9.3
17:49:12 2626 1.3
17:49:13 7954 12.0
17:49:13 7969 6.3
17:49:13 2626 1.2
17:49:14 7954 14.7
17:49:14 7969 8.5
17:49:14 2626 2.1
到目前为止我的想法:使用命令
top -b -n 1 -p 7954 | tail -n 2 | head -n 2 | awk '{print $1, $9}' >> logfile
我通过PID过滤顶部(在这种情况下PID == 7954),输出看起来像
PID %CPU
7954 6.6
然而(因为我实际上想要通过COMMAND文件管理器)我不知道如何通过COMMAND过滤。 在上面的行中,“-p 7954”对PID == 7954进行过滤,但是我需要在此处写什么来过滤COMMAND == chrome? 另外,如何删除/避免标题?
根据时间步骤:我发现了命令
date +"%T"
给我时间格式正确(hh:mm:ss)。
所以我只是努力将这些部分放在一起并修复上面提到的过滤问题。 感谢您的任何帮助!
Awk可以做到这一点; awk '/regex/ { print }'
仅在匹配regex
行上执行print
操作。
但是,你也可以(也许也应该)包含head
和tail
:
top -b -n 1 | awk 'NR>1 && $10 == "chrome" {print strftime("%T"), $1, $9}'
...假设top
输出的第十个字段包含命令名称。
但是我需要在这里写什么来过滤COMMAND == chrome
写一个calc_proc_mem
完成这个,比如calc_proc_mem
,如下所示:
#!/bin/bash
if [ -z "$1" ] #checking if first param exist
then
echo "Usage : cal_proc_mem process_name"
exit 1 # Exiting with a non-zero value
else
proc_ids=( $(pgrep "$1") )
if [ ${#proc_ids[@]} -eq 0 ] #checking if if pgrep returned nothing
then
echo "$1 : Process Not Running/No such process"
exit 1 # Exiting with a non-zero value
else
echo "$1's %CPU-%MEM usage as on $(date +%F)" >> logfile
while true
do
for proc_id in "${proc_ids[@]}"
do
usage="$(ps -p "$proc_id" -o %cpu,%mem | awk -v pid=$proc_id 'NR==2{printf "PID : %-10d \%CPU : %f \%MEM : %f\n",pid,$1,$2}' 2>/dev/null)"
echo -e "$(date +%H:%M:%S)\t$usage" >> logfile
done
sleep 3
done
fi
fi
运行脚本为
./calc_proc_mem process_name
样本输出
chrome's %CPU-%MEM usage as on 2016-06-27
23:40:33 PID : 3983 %CPU : 1.300000 %MEM : 2.200000
23:40:33 PID : 8448 %CPU : 0.100000 %MEM : 4.300000
23:40:33 PID : 8464 %CPU : 0.000000 %MEM : 0.400000
23:40:33 PID : 8470 %CPU : 0.000000 %MEM : 0.200000
23:40:33 PID : 8526 %CPU : 0.000000 %MEM : 3.000000
23:40:33 PID : 8529 %CPU : 0.000000 %MEM : 0.200000
23:40:33 PID : 8563 %CPU : 0.000000 %MEM : 1.500000
23:40:33 PID : 8655 %CPU : 0.300000 %MEM : 4.900000
23:40:33 PID : 32450 %CPU : 0.300000 %MEM : 2.100000
注意
由于您无限while-loop
运行,因此需要使用Ctrl C手动终止程序。
您可以删除'-p PID'选项,然后按命令删除grep。 你可以做下一个:
top -b -n 1 | grep 'chrome' | tail -n 2 | head -n 2 | awk '{print $1, $9}'
另一个让你前往的命令示例可能是:
$ cmd="sleep"; for j in {1..3}; do (${cmd} 123 &); done;
$ ts=$(date +"%T"); top -b -n 1| sed s/^[^\ 0123456789].*$//g |grep "${cmd}"|tr -s '\n'| awk '{print $1, $9, $12}'|sed s/^/"${ts} "/g
19:36:51 35122 0.0 sleep
19:36:51 35124 0.0 sleep
19:36:51 35126 0.0 sleep
它打印日期调用给出的时间,从顶部开始:找到PID,%CPU和COMMAND字段。 标题和非匹配数据行通过sed进行过滤(开始时没有数字,这可以通过方式抑制小pid =(因此也可以接受行开始处的空格)和命令上的grep。时间预先设置为pyd行开始注入存储的时间戳和空格分隔。
它不优雅,但可能符合您的需求,有一个开始。
pgrep解决方案或使用带正则表达式的awk看起来更好......但至少我很乐意尝试用top解决它。 管道中的尾部和头部阶段对我来说很可疑......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.