过滤顶部命令输出

smo*_*uns 12 bash awk command-line top macos

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

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

top -pid 1234
Run Code Online (Sandbox Code Playgroud)

但是,这会为该过程显示超过 15 列。我可以将“命令”的输出通过管道传输到 awk 并仅显示:

PID COMMAND %CPU
Run Code Online (Sandbox Code Playgroud)

列?

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

Dan*_*eck 9

top -pid 3907 -stats "pid,command,cpu"
Run Code Online (Sandbox Code Playgroud)
  • -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 
Run Code Online (Sandbox Code Playgroud)

使用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 
Run Code Online (Sandbox Code Playgroud)


vte*_*est 6

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

  1. 只需运行top,不带任何参数:

    $ 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 以交互模式运行。这不适合我,我想捕获相关数据并打印它。之后我将处理交互显示数据的任务。来自顶级联机帮助页的相关引用:

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

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

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

    $ top -b -n 1

  3. 我知道我想查看的 PID,所以我会在顶部添加一个更多的限制,所以它只打印有关该进程的数据:

    $ 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 脚本中。我将其称为3top,强调该名称是因为稍后会使用它:

    #!/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}'

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

    $ ./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 来进行实时监控。

  • 用户在 OS X 上并且没有 Gnu `top`。*无效的选项或语法:-b*。不知道为什么这会被反复投票。 (11认同)
  • Gnu `top`(在 `procps` 中)不能使用 Homebrew、MacPorts 或 Fink 安装,也不能使用 `make` 或 `cc top.c` 从源代码编译。 (5认同)