Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 使用top命令捕获按命令筛选的进程的%CPU和PID_Linux_Bash - Fatal编程技术网

Linux 使用top命令捕获按命令筛选的进程的%CPU和PID

Linux 使用top命令捕获按命令筛选的进程的%CPU和PID,linux,bash,Linux,Bash,我需要编写一个Bash脚本来执行以下操作: 在“top”命令中,我想根据给定的命令过滤进程。下面我以Google Chrome为例,它在命令列中显示为“Chrome” 过滤后,可能会有零个、一个或多个进程剩下命令“chrome”(这只是为了强调,通常不存在一个进程有命令“chrome”) 现在,我想将当前时间(hh:mm:ss)、进程的PID和为此进程显示的%CPU值写入一个文件“logfile” 每秒重复步骤1至3一次 示例:假设有三个“chrome”进程,“logfile”中的输出应如下所示

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

  • 在“top”命令中,我想根据给定的命令过滤进程。下面我以Google Chrome为例,它在命令列中显示为“Chrome”
  • 过滤后,可能会有零个、一个或多个进程剩下命令“chrome”(这只是为了强调,通常不存在一个进程有命令“chrome”)
  • 现在,我想将当前时间(hh:mm:ss)、进程的PID和为此进程显示的%CPU值写入一个文件“logfile”
  • 每秒重复步骤1至3一次
  • 示例:假设有三个“chrome”进程,“logfile”中的输出应如下所示(前三秒):

    到目前为止我的想法:使用命令

        top -b -n 1 -p 7954 | tail -n 2 | head -n 2 | awk '{print $1, $9}' >> logfile
    
        date +"%T" 
    
    我按PID过滤top(在本例中,PID==7954),输出如下

        PID %CPU
        7954 6.6
    
    然而(因为我实际上想通过命令来管理文件),我不知道如何通过命令进行过滤。在上面的一行中,“-P7954”对PID==7954进行过滤,但是我需要在这里写些什么才能通过命令==chrome进行过滤?另外,如何删除/避免标题

    根据时间步长:我发现命令

        top -b -n 1 -p 7954 | tail -n 2 | head -n 2 | awk '{print $1, $9}' >> logfile
    
        date +"%T" 
    
    以正确的格式给我时间(hh:mm:ss)


    所以我只是努力把这些片段放在一起,解决上面提到的过滤问题。谢谢你的帮助

    Awk可以做到这一点
    awk'/regex/{print}'
    仅在与
    regex
    匹配的行上执行
    print
    操作

    但是,您也可以(或许也应该)将
    头部
    尾部
    包括在内:

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

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

    您可以删除“-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和命令字段。标题和不匹配的数据行通过sed(开始时没有数字,这可以通过以下方式抑制小的PID=(因此也可以接受行开始时的空格)和命令上的grep进行过滤。时间在行开始时预先设置,注入存储的时间戳和空格以分隔

    它并不优雅,但可能适合你的需要有一个开始

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

    然而,我需要在这里写些什么才能通过COMMAND==chrome进行过滤呢

    写一个小脚本来完成这个任务,比如说
    calc\u proc\u 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
    
    注意


    由于循环运行时有一个无限的
    ,因此需要使用Ctrl C手动终止程序。

    谢谢,目前为止运行得很好!:)唯一仍然缺少的是时间戳。我知道这可能是非常基本的,但我不知道如何将日期+“%”部分正确地添加到这行中;现在无法测试,但应该可以。需要呆呆地看,显然,虽然是完美的,但效果完美!再次感谢你——你帮了我很多忙!:)-b是个病人option@IgorGanapolsky不,它已经存在很长时间了,但也许你有一个真正古老的版本。我不能很快找到一个变更日志,但我模糊地回忆起它可能在非常旧的Debian Box上丢失了。嗨,谢谢你的回答,但是我认为tail和head是错误的(可能在我的帖子中是这样),因为它过滤掉了太多的chrome进程?嗨,如果你想要全部,你只需要删除tail和head命令。谢谢你的回答!这对我帮助很大,因为它最初是唯一一个解决我的时间戳问题的答案。我能用你的答案解决它。因此,我会接受你的答案,但在tripleee的编辑下,他的答案更优雅一点。尽管如此,我还是非常感谢你:)