【问题标题】:Capture %CPU and PID of processes filtered by COMMAND using top command使用 top 命令捕获由 COMMAND 过滤的进程的 %CPU 和 PID
【发布时间】:2016-10-29 19:12:07
【问题描述】:

我需要编写一个执行以下操作的 Bash 脚本:

  1. 在“top”命令中,我想通过给定的命令过滤进程。下面我以 Google Chrome 为例,它在 COMMAND 列中显示为“chrome”。
  2. 过滤后,可以有零个、一个或多个带有 COMMAND "chrome" 的进程(这只是为了强调通常不存在一个带有 COMMAND "chrome" 的进程)。
  3. 现在我想将当前时间 (hh:mm:ss)、进程的 PID 和为此进程显示的 %CPU 值写入文件“logfile”
  4. 每秒重复一次步骤 1 到 3。

示例:假设有三个“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) 给我时间。

所以我只是努力将这些部分放在一起并解决上面提到的过滤问题。感谢您的帮助!

【问题讨论】:

    标签: linux bash


    【解决方案1】:

    Awk 可以做到这一点; awk '/regex/ { print }' 仅对匹配 regex 的行执行 print 操作。

    但是,您也可以(或许也应该)包含 headtail

    top -b -n 1 | awk 'NR>1 && $10 == "chrome" {print strftime("%T"), $1, $9}' 
    

    ...假设top 输出的第十个字段包含命令名称。

    【讨论】:

    • 谢谢你到目前为止工作正常! :) 唯一仍然缺少的是时间戳。我知道这可能是非常基本的,但我只是不知道如何正确地将日期 +"%" 部分添加到这一行中
    • 添加strftime;现在无法测试,但这应该可以。不过,显然需要 Gawk
    • 是的,完美,完美!再次感谢你——你帮了我很多! :)
    • -b 是无效选项
    • @IgorGanapolsky 不,它已经存在很长时间了,但也许你有一个真正古老的版本。我无法快速找到更新日志,但我隐约记得它可能在真正旧的 Debian 机器上丢失了。
    【解决方案2】:

    您可以删除“-p PID”选项,然后通过命令 grep。您可以执行以下操作:

    top -b -n 1 | grep 'chrome' | tail -n 2 | head -n 2 | awk '{print $1, $9}'
    

    【讨论】:

    • 嗨,谢谢你的回答,但是我认为尾部和头部是错误的(因为它可能在我的帖子中),因为它过滤掉了太多的 chrome 进程?
    • 嗨,如果你想要它们,你只需要删除 tail 和 head 命令。问候。
    【解决方案3】:

    另一个帮助你的命令示例可能是:

    $ 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。时间在 py sed 上注入存储的时间戳和一个空格分隔的行首。

    它并不优雅,但可能适合您开始的需求。

    pgrep 解决方案或使用带有正则表达式的 awk 看起来更好......但至少我喜欢尝试用 top 解决它。管道中的尾部和头部阶段对我来说看起来很可疑......

    【讨论】:

    • 感谢您的回答!它对我帮助很大,因为它最初是解决我遇到的时间戳问题的唯一答案。我能够用你的答案解决它。因此,我会接受您的答案,但是通过 Tripleee 的编辑,他的答案会更加优雅。不过,非常感谢你:)
    【解决方案4】:

    但是我需要在这里写什么来通过 COMMAND==chrome 过滤

    写一个小脚本来完成这个,比如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 手动终止程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 2010-12-20
      • 2010-10-07
      • 1970-01-01
      • 1970-01-01
      • 2012-08-18
      • 1970-01-01
      相关资源
      最近更新 更多