簡體   English   中英

使用top命令捕獲由COMMAND過濾的進程的%CPU和PID

[英]Capture %CPU and PID of processes filtered by COMMAND using top command

我需要編寫一個執行以下操作的Bash腳本:

  1. 在“top”命令中,我想通過給定的COMMAND過濾進程。 在下文中,我使用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)。

所以我只是努力將這些部分放在一起並修復上面提到的過濾問題。 感謝您的任何幫助!

Awk可以做到這一點; awk '/regex/ { print }'僅在匹配regex行上執行print操作。

但是,你也可以(也許也應該)包含headtail

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM