将 TOP 命令的输出限制为特定的进程名称
Posted
技术标签:
【中文标题】将 TOP 命令的输出限制为特定的进程名称【英文标题】:Limit the output of the TOP command to a specific process name 【发布时间】:2011-04-13 06:29:12 【问题描述】:如果你调用 top 命令,你会得到所有正在运行的进程。但是我怎样才能限制输出仅到某个进程名称,如“java”?
我试过这个 顶部-l 2 | grep java 但通过这种方式,您只能获得快照,而不是不断更新的列表。和 top -l 0 | grep java 不是很清楚。
【问题讨论】:
不幸的是,到目前为止仍然没有有效的答案,因为 OS X 的 top 命令不支持 -p 和 -b。 我已经在下面发布了可能是第一个 OSX 解决方案 - 并且正好在紧要关头;) 【参考方案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 上你可以使用类似 pgreptop -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
部分。
【讨论】:
以上是关于将 TOP 命令的输出限制为特定的进程名称的主要内容,如果未能解决你的问题,请参考以下文章