【问题标题】:Limit the output of the TOP command to a specific process name将 TOP 命令的输出限制为特定的进程名称
【发布时间】:2011-04-13 06:29:12
【问题描述】:

如果你调用 top 命令,你会得到所有正在运行的进程。但是我怎样才能限制输出仅到某个进程名称,如“java”

我试过这个 顶部-l 2 | grep java 但通过这种方式,您只能获得快照,而不是不断更新的列表。和 top -l 0 | grep java 不是很清楚。

【问题讨论】:

  • 不幸的是,到目前为止仍然没有有效的答案,因为 OS X 的 top 命令不支持 -p 和 -b。
  • 我已经在下面发布了可能是第一个 OSX 解决方案 - 并且正好在紧要关头;)

标签: macos unix command-line top-command


【解决方案1】:

我更喜欢以下内容,因此我仍然可以交互地使用 top,而不必每次运行时都查找 pid:

top -p `pgrep process-name | tr "\\n" "," | sed 's/,$//'`

当然,如果进程发生变化,您将不得不重新运行命令。

解释:

  • pgrep process-name 返回由换行符分隔的进程 ID 列表
  • tr "\\n" "," 将这些换行符转换为逗号,因为 top 想要一个以逗号分隔的进程 ID 列表
  • sed 是一个流编辑器,这里使用sed 's/,$//' 去除尾随的逗号

【讨论】:

  • 最佳答案,改进了 dogbane,因此您可以实际输入名称而不是粘贴大量 PID。 (就是这样)
  • 如果可以的话,我会多次投票给你,我认为这真的应该是“接受”的答案。
  • 我收到了top: pid limit (20) exceeded。反正有这个限制吗?
  • @celwell,请尝试top -p $(pgrep process-name | head -20 | tr "\\n" "," | sed 's/,$//')。这将显示pgrep 返回的前 20 个 PID 的数据。
  • 在优胜美地(或更早?)它是 -pid 而不是 -p
【解决方案2】:

找到您要监控的进程的 pid,然后使用 -p 选项,该选项允许您向 top 命令提供 pid 列表。

例子:

top -p 18884 -p 18892 -p 18919

  PID USER     PRI  NI  SIZE  RSS SHARE STAT %CPU %MEM   TIME CPU COMMAND
18884 user  25   0  672M  95M  9476 S     0.0  1.1   0:02   1 java
18892 user  25   0 2280M 123M 12252 S     0.0  1.5   0:05   1 java
18919 user  22   0 1492M 198M 28708 S     0.0  2.4   0:07   1 java

(相信你也可以传入逗号分隔的列表。)

【讨论】:

  • 在 Mac 上应该是“top -pid ID”,但 Java 进程可能有多个不同的 ID,因为可能有多个 java 进程。
【解决方案3】:

怎么样top -b | grep java

【讨论】:

  • 不适用于 Mac,因为 Mac 使用 BSD 工具而不是 GPL 工具。并且存在一些差异。我想“-b”版本类似于“-l 0”但也打印了表格的标题?
【解决方案4】:

扩展@dogbane's answer,您可以使用pgrep 获取命名进程的所有PID,以执行以下操作:

top -p "$(pgrep -d ',' java)"

【讨论】:

  • 这有 20 个 pid 的最大限制
  • top -p "$(pgrep -d ',' php)" top: pid limit (20) exceeded
  • 你是对的! man top 说“这个选项最多可以给出 20 次,或者您可以提供一个逗号分隔的列表,最多包含 20 个 pid。”好吧。
【解决方案5】:

使用 watch 命令

watch -d 'top -n1 | grep mysql'

【讨论】:

  • 应该是“watch --d”。但是执行此命令时我没有得到任何输出。
  • -1: man watch: "watch 反复运行命令,显示其输出和错误";它不会像top 那样显示当前正在运行的进程
  • @AlexanderOrlov,这里没有什么特别的魔法,直接用top -n1打印退出,用watch连续监控。
  • @sdaau,您的评论与我的回答无关,请下次认真回复。
  • 我认为我们应该添加 -b 选项。 watch -d 'top -b -n1 | grep mysql'
【解决方案6】:

使用来自here 的答案,我能够创建一个衬里

top -pid $(pgrep process_name | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ -pid /g')

这适用于我在 MacOS 10.12 (Sierra) 上

【讨论】:

    【解决方案7】:

    我使用以下方法解决了我的问题:

    顶部 -n1 -b | grep "进程名"

    在这种情况下: -n 用于设置 top 将进行多少次处理
    -b 用于显示所有 pid

    它可以防止以下错误: 顶部:超过 pid 限制 (20)

    【讨论】:

      【解决方案8】:

      以下代码通过 watch 命令每 5 秒更新一次进程列表:

      watch -n 5 -t top -b -n 1 -p$(pgrep java | head -20 | tr "\\n" "," | sed 's/,$//')

      【讨论】:

        【解决方案9】:

        我运行它(例如):top -b | egrep -w 'java|mysqld'

        【讨论】:

          【解决方案10】:

          假设..如果我们在服务器上运行的同名进程超过 20 个......这将无济于事

          顶部 -p pgrep oracle | head -n 20 | tr "\\n" "," | sed 's/,$//'

          它将尝试列出并提供 20 个进程的实时输出,我们很有可能会错过其他消耗更多资源的进程 ....

          我仍在寻找更好的选择

          【讨论】:

            【解决方案11】:

            一个更具体的案例,就像我真正在寻找的那样:

            对于 Java 进程,您还可以使用 jps -q,其中 jps 是来自 $JAVA_HOME/bin 的工具,因此应该在您的$PATH。

            【讨论】:

              【解决方案12】:

              我来这里是为了在 OSX 上寻找答案。我最终得到了我想要的 bash 和 awk:

              topfiltered() {
                [[ -z "$1" ]] && return
                dump="/tmp/top_dump"
                rm -f "$dump"
                while :; do
                  clear
                  [[ -s "$dump" ]] && head -n $(( $LINES - 1 )) "$dump"
                  top -l 1 -o cpu -ncols $(( $COLUMNS / 8 )) | awk -v p="$(pgrep -d ' ' $@)" '
                      BEGIN { split(p, arr); for (k in arr) pids[arr[k]]=1 }
                      NR<=12 || ($1 in pids)
                  ' >"$dump"
                done
              }
              

              我在日志模式下循环顶部并使用 awk 过滤它,从 pgrep 的输出构建一个关联数组。 awk 打印前 12 行,其中第 12 行是列标题,然后是具有作为数组中键的 pid 的每一行。转储文件用于更可观察的循环。

              【讨论】:

              • 在 OSX 上你可以使用类似 pgrep 的东西;顶部 -pid
              【解决方案13】:

              top -bn 1 | grep java 会帮你搞定

              【讨论】:

                【解决方案14】:

                运行以下命令将在控制台中持续更新:

                bcsmc2rtese001 [~]$ echo $SHELL  
                /bin/bash  
                bcsmc2rtese001 [~]$ top | grep efare  or watch -d 'top | grep efare' or top -p pid
                27728 efare     15   0 75184 3180 1124 S  0.3  0.0 728:28.93 tclsh  
                27728 efare     15   0 75184 3180 1124 S  0.7  0.0 728:28.95 tclsh
                

                【讨论】:

                  【解决方案15】:

                  这是目前唯一适用于 MacOS 的解决方案:

                  top -pid `pgrep java | awk 'ORS=" -pid "' | sed 's/.\{6\}$//'`
                  

                  尽管如果没有java 进程处于活动状态,这将不受欢迎地报告invalid option or syntax: -pid

                  解释

                  此处发布的其他解决方案使用top -p id1,id2,id3 格式,但MacOS 的top 仅支持笨重的top -pid id1 -pid id2 -pid id3 格式。

                  首先,我们获取进程名称为“java”的进程ID列表:

                  pgrep java
                  

                  我们通过管道将其传送到awk,它将结果与分隔符" -pid " 连接起来

                  | awk 'ORS=" -pid "'
                  

                  唉,这留下了一个尾随分隔符!例如,我们可能到目前为止已经获得了字符串"123 -pid 456 -pid 789 -pid "

                  然后,我们只需使用sed 去除分隔符的最后 6 个字符。

                  | sed 's/.\{6\}$//'`
                  

                  我们已准备好将结果传递给top

                  top -pid `...`
                  

                  【讨论】:

                    【解决方案16】:

                    获取进程的pid:

                    # pidof <process>
                    

                    告诉顶部要显示什么进程 pid

                    # top -p <pid1>,<pid2>, etc
                    

                    示例:

                    landis@linux-e6510:~>pidof konsole
                    1841 1709
                    landis@linux-e6510:~>top -p 1841,1709
                    

                    Top 将只显示 2 个“konsole”进程。 这在通过 ssh 的繁忙服务器上很有用,而不必通过 grep 管道。

                    【讨论】:

                    • 抱歉,没有看到有问题的macos标签。我的适用于我所有的 linux 机器。
                    【解决方案17】:

                    您需要将pgrep {proc_name} 的输出提供给top -pid {pid_No}top -pid 的问题在于它在您要监控的每个 pid 之前都需要 -pid

                    在 zsh 中的 Mac 上,我可以处理这个问题,例如像这样:

                    top `pgrep proc_name | awk '{printf " -pid %d",$1}'`

                    这也不理想,因为pgrep 在进程名称中查找子字符串。例如。 pgrep dd 可以返回 icdd, hidd, cloudd 等的结果。选项 pgrep -x 应该只返回完全匹配的内容(如 grep -w)。但它在 Mac Terminal 中对我不起作用,尽管它在 Ubuntu 虚拟机中起作用。

                    【讨论】:

                      【解决方案18】:

                      使用 Rick Byers 的回答中提到的方法:

                      top -p `pgrep java | paste -sd "," -`
                      

                      但我有超过 20 个进程正在运行,因此以下命令可能对遇到类似情况的人有所帮助。

                      top -p `pgrep java | head -n 20 | paste -sd "," -`
                      

                      pgrep 获取具有给定名称的进程列表 - 在本例中为 java。 head 用于获取前 20 个 pid,因为 top 在使用 -p 参数时无法处理超过 20 个 pid。最后paste 以',' 加入pids 列表。

                      您可以在上述命令中控制您要查找的进程名称以及您有兴趣查看的具有该名称的进程的数量。如果给定名称的进程数少于 20,则可以忽略 head -n 20 部分。

                      【讨论】:

                        猜你喜欢
                        • 2015-07-02
                        • 1970-01-01
                        • 1970-01-01
                        • 2012-08-18
                        • 1970-01-01
                        • 2022-01-22
                        • 2015-12-26
                        • 2014-10-30
                        • 1970-01-01
                        相关资源
                        最近更新 更多