过滤 top 命令输出

过滤 top 命令输出

我正在运行 Mac,并且想要过滤特定进程的命令输出top,以便仅显示 PID、COMMAND 和 %CPU 列。

获取进程的 PID 后,我运行:

top -pid 1234

但是,这会显示该进程的 15 列以上。我可以将命令的输出通过管道传输到 awk 并仅显示以下内容吗:

PID COMMAND %CPU

列?

我不想将输出存储在文本文件中,然后对其进行处理。我对实时监控该过程感兴趣。

答案1

top -pid 3907 -stats "pid,command,cpu"
  • -pid 3907:你的进程 ID
  • -stats pid,command,cpu:仅显示进程 ID、名称和 CPU%

无需awk在输出上运行。


如果要对输出进行后处理,请使用-l 0运行日志记录模式(0 表示无限,其他所有值都限制样本数量)。输出将如下所示(重复两次):

Processes: 72 total, 3 running, 1 stuck, 68 sleeping, 326 threads 
2011/05/10 19:15:13
Load Avg: 0.14, 0.14, 0.09 
CPU usage: 20.0% user, 26.66% sys, 53.33% idle 
SharedLibs: 5304K resident, 5208K data, 0B linkedit.
MemRegions: 16345 total, 1048M resident, 54M private, 338M shared.
PhysMem: 726M wired, 1802M active, 687M inactive, 3215M used, 750M free.
VM: 169G vsize, 1036M framework vsize, 5261732(0) pageins, 552476(0) pageouts.
Networks: packets: 46747406/52G in, 32528901/3715M out.
Disks: 9452898/244G read, 11226269/293G written.

PID   COMMAND      %CPU
3907  WindowServer 0.0 
Processes: 72 total, 3 running, 1 stuck, 68 sleeping, 326 threads 
2011/05/10 19:15:14
Load Avg: 0.13, 0.14, 0.09 
CPU usage: 0.95% user, 1.90% sys, 97.14% idle 
SharedLibs: 5304K resident, 5208K data, 0B linkedit.
MemRegions: 16346 total, 906M resident, 54M private, 386M shared.
PhysMem: 726M wired, 1802M active, 687M inactive, 3215M used, 751M free.
VM: 169G vsize, 1036M framework vsize, 5261732(0) pageins, 552476(0) pageouts.
Networks: packets: 46747406/52G in, 32528901/3715M out.
Disks: 9452898/244G read, 11226269/293G written.

PID   COMMAND      %CPU
3907  WindowServer 2.7 

使用awk或类似工具仅显示每 13 行(因为这些行包含该示例中的值):

$ top -l 0 -pid 3907 -stats pid,command,cpu | awk 'NR%13==0'
3907  WindowServer 0.0 
3907  WindowServer 1.3 
3907  WindowServer 2.2 

答案2

这当然可以做到,我将解释我将如何做到。我并不是假装这是最佳方法,但它确实有效。我使用的是 Linux(和 bash shell),所以我的 top 的默认行为可能略有不同。因此,您可能需要针对您的特定场景调整此迷你指南。

  1. 赶紧跑顶部,不带任何参数:

    $ top

    以下是我的输出的标题和相关行:

    PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

    2569 user 20 0 339m 86m 10m S 7.8 6.9 6:42.99 java

    我选择了一个在内存中停留一段时间并实际消耗 CPU 的进程,我将使用它作为测试进程来达到最终目标。

  2. 默认情况下,top 以交互模式运行。这不适合我,我想捕获相关数据并打印出来。之后我将处理以交互方式显示数据的任务。来自 top manpage 的相关引述:

    -b:批处理模式操作以“批处理模式”启动 top,这对于将 top 的输出发送到其他程序或文件非常有用。在此模式下,top 将不接受输入并运行,直到达到您使用“-n”命令行选项设置的迭代限制或被终止。

    -n:迭代次数限制为:-n 数字指定 top 在结束前应产生的最大迭代次数或帧数。

    这是调整后的 top 命令,它仅打印一次输出,然后退出:

    $ top -b -n 1

  3. 我知道我想要监视的 PID,因此我将向 top 添加一个限制,这样它就只打印有关该进程的数据:

    $ top -b -n 1 -p 2569

  4. 即使在批处理模式下,top 仍会打印标题,其中包含各种系统范围的统计数据,如正常运行时间、可用内存/交换等。我不需要这个。我只需要一行 - 包含有关我的进程的数据,因此我将从整个输出中剪切它,如下所示:

    $ top -b -n 1 -p 2569 | tail -n 2 | head -n 1

    正如你所见,我从 1 中得到了第二行。

  5. 我将通过管道将此行传送到 awk 以仅提取我需要的列:

    $ top -b -n 1 -p 2569 | tail -n 2 | head -n 1 | awk '{print $1, $12, $9}'

  6. 到目前为止,我一直在命令行中进行这些操作,现在是时候为我们的硬编码特定情况添加一些持久性和灵活性了。我将整行移到一个简单的 shell 脚本中。我将其称为3顶部,之所以强调这个名字,是因为后面会用到它:

    #!/bin/bash

    top -b -n 1 -p 2569 | tail -n 2 | head -n 1 | awk '{print $1, $12, $9}'

  7. PID 号是硬编码的,下面是如何使脚本接受它作为命令行参数:

    #!/bin/bash

    top -b -n 1 -p "$1" | tail -n 2 | head -n 1 | awk '{print $1, $12, $9}'

    要使 3top 显示有关 PID 2569 的统计信息,必须像这样调用它:

    $ ./3top 2569

  8. 我还想在 CPU 负载后显示百分比,因此我对 3top 脚本进行了如下调整:

    #!/bin/bash

    out=$(top -b -n 1 -p "$1" | tail -n 2 | head -n 1 | awk '{print $1, $12, $9}')

    echo "$out%"

    我将整个命令链(通过管道连接)的输出重定向到一个变量中。然后我只需使用 echo 打印它并在末尾添加一个“%”,因为 CPU 负载是最后一个字段

  9. 此时,我有一个批处理脚本,它接受 PID 作为参数并打印一次统计信息。想要实时监控吗?这很容易,因为手表可以做到!像这样运行脚本:

    $ watch -n 1 3top 2569

    它将通过每秒运行一次 3top 进行实时监控。

答案3

显示格式top可以自定义,但无法在命令行指定显示选项。不过,如果你有创造力,你也许可以通过巧妙地操作文件来做你需要的事情~/.toprc

假设您尚未自定义显示top(并且没有文件~/.toprc):

  1. 发射top
  2. 按下f进入字段选择模式。
  3. 对于每个带有 的*不需要的字段,按相应的字母可取消选择该字段。例如,按e可取消选择该User Name字段。完成后,您应该只在、和*旁边有一个。Process IdCPU usageCommand name/line
  4. 按下Space返回主窗口。
  5. W(即Shift+ w)将当前布局保存到您的~/.toprc文件中。
  6. 退出top,然后重新启动以验证您的设置是否已保存。
  7. 当您想要返回默认布局时,将其重命名~/.toprc为类似于~/min.toprc启动之前 的名称top。当您想要切换到最小布局时,将其重命名~/min.toprc~/.toprc启动之前 的名称top

对于那些比我更有经验和知识的人来说,这个文件重命名和启动可能可以写成一个简单的 shell 脚本。如果您的常规布局已经定制,top则需要特别注意。top

相关内容