1

I am trying to list all of the real users via the command line along with a number of their processes, example:

root 73
user1 51
user2 68

I have tried several commands yet failed to get the output as written. These two are the ones I think should be the most appropriate for listing users only:

awk -F':' '{ if($3 >= 1000) print $1 }' /etc/passwd  

(does not list root since his PID is 0)

awk -F':' '$2 ~ "\$" {print $1}' /etc/shadow 

(requires root)

I am also aware that ps command is used for listing all processes, however my question is how to print specific number of processes per user after they are printed via command?

Not sure if piping is a solution, wc -l might help here for counting as well. Thanks.

2
  • What do you mean by: my question is how to print specific number of processes per user after they are printed via command? Easy to get the output as you describe via ps -u. Nov 18, 2015 at 22:17
  • What I have meant by that is to add the number of processes after the username (look example) Since I believe it is not possible to solve it via piping, as in: awk -F':' '{ if($3 >= 1000) print $1 }' /etc/passwd | ps aux | wc -l
    – box1337
    Nov 18, 2015 at 22:28

3 Answers 3

2

pgrep can print the number of processes for a given user, and xargs uns a program for every line of its input. Put that together with your ´awk` command:

(echo root; awk -F: '{if($3>=1000)print $1}' /etc/passwd) | xargs -i sh -c 'echo "{} $(pgrep -cu {})"'

I'm adding root manually to the output of awk. One could use

if($3>=1000 || $3==0)

in the awk command instead.

1
  • Exactly what I have been looking for, thank you very much!
    – box1337
    Nov 18, 2015 at 22:57
2

Take advantage of the /proc filesystem: Your shell is bash, so:

shopt -s extglob
stat -c '%U %u' /proc/+([0-9])/ | awk '$2 >= 1000 {print $1}' | sort | uniq -c
3
  • First, the files are owned by system users with uid < 1000, so no big deal, those get filtered out. Second, each numbered directory represents a process, and the OP only wants a number of processes owned by each user, so why would I need to examine any files inside that dir? Third, yes, I could restrict the list of dirs sent to stat -- I'll update my answer for that. Nov 19, 2015 at 1:47
  • I've seen your edit, looks good. Also, I missed that OP wanted the number of the processes. OK, good solution. Comment removed and the answer upvoted. In the mean time I will also edit mine a bit Nov 19, 2015 at 4:13
  • For some reason I get one process marked as unknown during the output. I get: 92 user 1 UNKNOWN
    – box1337
    Nov 19, 2015 at 10:10
0

There is a simpler approach that uses ps formating options and AWK

We know that by default, human users have UID that ranges from 1000 to 65533 ( UID 65534 is nobody user ).

We also know that ps has formatting flag -o , where we can choose to output UID as well as the process. The format would be the following ( note that I am showing here only 5 first lines )

ps -eo uid,cmd | head -n 5                                           
  UID CMD
    0 /sbin/init
    0 [kthreadd]
    0 [ksoftirqd/0]
    0 [kworker/0:0H]

Thus, we can do

ps -eo uid,cmd | awk '$1 >= 1000 && $1 < 65534 ' 

AWK helps us to print all lines where column 1, the UID is greater or equal to 1000 AND less than 635534.

Sample output from my system (where I have only one user ):

$ ps -eo uid,cmd | awk '$1 >= 1000 && $1 < 635534 ' | tail -n 5        
 1000 /usr/lib/at-spi2-core/at-spi2-registryd --use-gnome-session
 1000 /usr/lib/firefox/firefox google.com
 1000 ps -eo uid,cmd
 1000 awk $1 >= 1000 && $1 < 635534 
 1000 tail -n 5

EDIT

I've realized that OP wanted the number of processes used by human users.

If all you really care about is the number of processes that belong to human users, here's a quick solution:

ps --no-headers -eo uid,args --sort=uid | awk '$1 >= 1000 && $1 < 65534 {counter++}; END{print counter" human processes"}'

As for my previous solution, I've improved the AWK command, which uses associative arrays, based on UID, as well as added additional flags to ps command to include username and sort the output by UID.

 ps -eo uid,euser,cmd --sort=uid | awk '$1 >= 1000 && $1 < 65534 { HUMAN++; procTotals[$1]++; if( $1 > UID  ) username[$1]=$2; UID=$1  }  END{ print "Out of "NR" processes, "HUMAN" belong to human users";   for(i=1000;i<=UID;i++ )  print  username[i]":"procTotals[i] }'

Sample output:

xieerqi:$ ps -eo uid,euser,cmd --sort=uid | awk '$1 >= 1000 && $1 < 65534 { HUMAN++; >
Out of 215 processes, 88 belong to human users
xieerqi:84
testuser:4

For better readability , here's the formated code. Note that awk portion could be turned into a script with #!/usr/bin/awk -f shebang line

ps -eo uid,euser,cmd --sort=uid | awk '$1 >= 1000 && $1 < 65534 { 

HUMAN++; procTotals[$1]++; 
if( $1 > UID  ) username[$1]=$2; UID=$1  

}

END{ print "Out of "NR" processes, "HUMAN" belong to human users";   

for(i=1000;i<=UID;i++ )  
    print  username[i]":"procTotals[i] 

}'
1
  • I like this one as well, quite simple to understand however I wanted to include root as one of users as well. Could it be somehow added by any chance?
    – box1337
    Nov 19, 2015 at 10:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .