Take the 2-minute tour ×

I got a requirement to filter the process results with user context. I am using command like.

# top -b -n 1 -p $(pgrep -d',' http)
top - 14:44:13 up 7 days,  3:01,  6 users,  load average: 0.05, 0.01, 0.00
Cpu(s):  1.0%us,  1.4%sy,  0.0%ni, 97.4%id,  0.1%wa,  0.0%hi,  0.1%si,  0.0%st
Mem:   8062112k total,  4471344k used,  3590768k free,   176040k buffers
Swap:  6160376k total,       88k used,  6160288k free,   797580k cached

27720 root      20   0  175m 3708 1408 S  0.0  0.0   0:05.79 httpd              
27722 daemon    20   0  175m 3076  708 S  0.0  0.0   0:00.00 httpd              
27723 daemon    20   0 2417m 176m  13m S  0.0  2.2   0:43.19 httpd  

And I want to get the 'process id' which is under 'root' user context.

share|improve this question
add comment

3 Answers

The best tool for this would probably be ps:

   ps displays information about a selection of the active
   processes.  If you want a repetitive update of the selection
   and the displayed information, use top(1) instead.

The relevant options here are:

   -C cmdlist
          Select by command name.  This selects the processes
          whose executable name is given in cmdlist.
   -o format
          User-defined format.  format is a single argument in
          which offers a way to specify individual output
          columns.  The recognized keywords are described in the
          STANDARD FORMAT SPECIFIERS section below. 

So, to find all httpd processes that have been launched by root:

$ ps -C httpd -o pid,user
27720 root
27722 daemon
27723 daemon

Theoretically. passing the -u root option to ps should return only those processes run by root but that doesn't work on my system, not sure why. So we parse:

$ ps -C httpd -o pid,user | gawk '$2==root{print $1}'
share|improve this answer
While that is commonly the case (and it certainly is the case in this particular instance), do note that the awk expression depends on the fact that the desired username does not contain whitespace. –  Michael Kjörling Apr 1 '13 at 16:33
@MichaelKjörling can a *nix username contain whitespace? –  terdon Apr 1 '13 at 16:35
Good point, you caught me on that one. I'm not sure, but especially in a mixed environment, I don't really see why not. –  Michael Kjörling Apr 1 '13 at 16:40
I would think that it can't precisely because that would cause problems like what you suggest :). In any case, my debian won't let me create a username that contains a space and I really doubt that any *nix will. –  terdon Apr 1 '13 at 16:50
What the tools let you do is one thing; what you can do hacking /etc/passwd (which would be closer to "can it?") is something very different. :) –  Michael Kjörling Apr 1 '13 at 16:51
add comment

pgrep supports filtering by process user too:

pgrep -u root httpd

If you want instead to extract the PID from your top output, try this awk one-liner:

($NF=="httpd" && $2=="root") {print $1}


  gawk '($NF=="httpd" && $2=="root") {print $1}'

Another sometimes useful pgrep option is -o for oldest matching process, which should be the top-level httpd listener process (pgrep is smart enough to try to do the right thing when matching processes have the "same" start time).

Apache is also usually configured to record a pid file, typically somewhere like /usr/local/apache2/logs/httpd.pid or /var/run/httpd.pid, that should contain the top-level PID too (though it's slightly less trustworthy as it can be stale).

share|improve this answer
add comment

On Linux, assuming /proc is available (if not, you probably have bigger problems getting a complete view of the running processes), you can get the PIDs of all processes belonging to root using a command like the following:

find /proc -maxdepth 1 -type d -regex '^/proc/[1-9][0-9]*$' -uid 0 -print \
| sed 's,/proc/,,g'

Strictly speaking, this will list all directories directly inside /proc which have a name starting with a non-zero digit followed by any number of digits. It then uses sed to remove the /proc/ at the beginning of each line of output, leaving you with simply the numerical PIDs.

The output of this can be further passed to whatever process you like; it'll simply be a list of PIDs, one per line. For example, you could pipe the output to a loop like while read pid; do something $pid; done to do something to each PID in turn.

On my system the output appears to be sorted numerically but I don't think you can count on that always being the case. sort will come in handy otherwise (and depending on what you want to do you may be particularly interested in something like sort -rn for a reverse numerical sort).

The -uid 0 part can be replaced to reference whatever numerical UID you want (or see the find man page for other possibilities; for example, -gid). If you are interested in your own processes rather than root's, something like id -u will come in handy (-uid $(id -u)).

share|improve this answer
add comment

Your Answer


