如果你调用 top 命令,你会得到所有正在运行的进程。但是我怎样才能将输出限制为某个进程名称,如“java”?
我试过这个 top -l 2 | grep java 但通过这种方式,您只能获得快照,而不是不断更新的列表。和顶部 -l 0 | grep java不是很清楚。
如果你调用 top 命令,你会得到所有正在运行的进程。但是我怎样才能将输出限制为某个进程名称,如“java”?
我试过这个 top -l 2 | grep java 但通过这种方式,您只能获得快照,而不是不断更新的列表。和顶部 -l 0 | grep java不是很清楚。
我更喜欢以下内容,因此我仍然可以交互地使用 top ,而不必在每次运行时查找 pid:
top -p `pgrep process-name | tr "\\n" "," | sed 's/,$//'`
当然,如果流程发生变化,您将不得不重新运行该命令。
解释:
pgrep process-name
返回由换行符分隔的进程 ID 列表tr "\\n" ","
将这些换行符转换为逗号,因为 top 想要一个以逗号分隔的进程 ID 列表sed
是一个流编辑器,sed 's/,$//'
在这里用来去掉结尾的逗号找到您要监视的进程的 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
(我相信你也可以传入一个逗号分隔的列表。)
top -b怎么样?grep java
扩展@dogbane 的答案,您可以获取命名进程的所有 PID,pgrep
并执行以下操作:
top -p "$(pgrep -d ',' java)"
使用监视命令
watch -d 'top -n1 | grep mysql'
使用此处的答案,我能够创建一个衬里
top -pid $(pgrep process_name | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/ -pid /g')
这适用于 MacOS 10.12 (Sierra)
我使用以下方法解决了我的问题:
顶部 -n1 -b | grep "进程名称"
在这种情况下: -n 用于设置 top 将多少次 proccess
和 -b 用于显示所有 pid
它可以防止以下错误:top: pid limit (20) exceeded
以下代码通过 watch 命令每 5 秒更新一次进程列表:
watch -n 5 -t top -b -n 1 -p$(pgrep java | head -20 | tr "\\n" "," | sed 's/,$//')
我运行它(例如):top -b | egrep -w 'java|mysqld'
假设..如果我们在服务器上运行的同名进程超过 20 个......这将无济于事
顶部 -ppgrep oracle | head -n 20 | tr "\\n" "," | sed 's/,$//'
它将尝试列出并提供 20 个进程的实时输出,我们很有可能错过其他消耗更多资源的进程......
我仍在寻找更好的选择
I came here looking for the answer to this on OSX. I ended up getting what I wanted with bash and 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
}
I loop top in logging mode and filter it with awk, building an associative array from the output of pgrep. Awk prints the first 12 lines, where line 12 is the column headers, and then every line which has a pid that's a key in the array. The dump file is used for a more watchable loop.
只会top -bn 1 | grep java
为你解决问题
一个更具体的案例,就像我实际上正在寻找的那样:
对于Java 进程,您还可以使用jpsjps -q
是来自$JAVA_HOME/bin的工具,因此应该在您的 $PATH 中。
运行以下命令将在控制台中持续更新:
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
获取进程的pid:
# pidof <process>
告诉 top 要显示什么进程 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 进行管道传输。
您需要提供 to 的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 虚拟机中起作用。
这是迄今为止 MacOS的唯一解决方案:
top -pid `pgrep java | awk 'ORS=" -pid "' | sed 's/.\{6\}$//'`
尽管invalid option or syntax: -pid
如果没有java
进程处于活动状态,这将是不受欢迎的报告。
解释
此处发布的其他解决方案使用该格式top -p id1,id2,id3
,但 MacOStop
仅支持笨重的格式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 `...`
使用 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
用 ',' 加入 pid 列表。
您可以在上述命令中控制您要查找的进程名称以及您有兴趣查看的具有该名称的进程数。head -n 20
如果具有给定名称的进程数少于 20,则可以忽略该部分。