Linux Top command with more than 20 commands
Asked Answered
L

2

4

I want to use top in order to monitor numerous processes by process name. I already know about doing $ top -p $(pgrep -d ',' <pattern>) but top only limits me to 20 pids. Is there a way to allow for more than 20 pids?

Do I have to use a combination of ps and watch to get similar results?

Luke answered 14/8, 2014 at 19:19 Comment(1)
Try ps auxw it should list all the processes. You might need to be root to get all of them.Bullis
D
7

From top/top.c:

if (Monpidsidx >= MONPIDMAX)
    error_exit(fmtmk(N_fmt(LIMIT_exceed_fmt), MONPIDMAX));

(where LIMIT_exceed_fmt is the error message you're getting).

And in top/top.h:

#define MONPIDMAX  20

I changed this number to 80, and that seems to work okay. Not sure why this hardcoded limit is so low.

So, if manually compiling procps-ng is an option, then you could do that. You don't need to replace the system top (or need root privileges), you can just put it in your homedir.

Another workaround might be using tmux or screen and multiple top instances.

Yet another possible solution might be using ps with a loop, ie.

#!/bin/sh

while :; do
    clear
    ps $*
    sleep 1
done

Invoke it as: ./psloop.sh 42 666

You may want to add more flags to ps for additional info. Also be aware this is less efficient, since it will invoke 3 binaries every second.

Duggins answered 14/8, 2014 at 19:30 Comment(1)
Perhaps the 20 pid limit has its roots in VT100, where the default terminal size was around 80x24, so limiting the process list to 20 would allow some summary info to be displayed at the top of top on one screen.Estradiol
C
2

A wrapper with watch. Tested with Ubuntu 11.04, Ubuntu 14.04, RHEL5, RHEL6 and RHEL7

Syntax: script.sh pid [ pid ...] # space separated


Example: script.sh $(pgrep -d ' ' <pattern>)
#!/bin/bash

i=10 # ~ interval in seconds

format()
{
  a="$1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12}"
  a="$a ${13} ${14} ${15} ${16} ${17} ${18} ${19} ${20}"
  a="${a%%*( )}"; a="${a// /,}"
}

main()
{
  format $@
  top -b -n 1 -p $a
  [ $# -gt 20 ] && shift 20 || shift $#

  until [ $# -eq 0 ]; do
    format $@
    top -b -n 1 -p $a | sed '1,/PID/d;/^$/d'
    [ $# -gt 20 ] && shift 20 || shift $#
  done
}

if [ "$1" == "watch" ]; then
  shift
  shopt -s extglob
  main $@
else
  watch -t -n $i "$0 watch $@"
fi
Coop answered 14/8, 2014 at 23:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.