Show what users are running processes on your Linux system

By | June 14, 2012

Typically the w command will show you who is logged in.  So do the users and who commands.  With the advent of Ubuntu’s unity and the lightdm desktop session manager, these commands don’t tell the whole truth.

Moreover, users don’t need to be logged in to a terminal (or pseudo terminal) in order to run processes or services.  If you want a quick and dirty way to see what’s going on, you can use the ps command.  Typically you use the “-a -u -f -x” flags with the command (ps aufx) if you want the information for all users in easily readable, tree-based, fully formatted output.  Pipe it through more or less.

Still, what if you only care about the users, and not all the gory details?  What if you just want to know what users are running processes? You can still use the ps command, but filter it through a few pipes: get rid of everything except the first column of output, chop off the header, sort the output, toss out duplicate lines, and there you have it — a simple list of users*

$ ps aux | awk '{ print $1 }' | sed '1 d' | sort | uniq

The above code will give you output like this:

103
avahi
colord
daemon
lp
nobody
postfix
root
rtkit
statd
superman
syslog

Now I’ll grant you that there are other ways to do this; you can fine-tune the output of the ps command using optional formatting arguments. The purpose of this example, however, is to illustrate the capabilities of the individual utilities in the chain of pipes, as described in the preceding paragraph.

If you want to customize it even further (and make it even more difficult to read ;-)), you can add a bit of Perl to the end of the command to filter out all system users and only show you the names of regular users (and/or the root user) with active processes:

$ ps aux | awk '{ print $1 }' | sed '1 d' | sort | uniq | perl -e 'for (<>) { chomp; $u = ( getpwnam($_) )[2]; print $_, "\n" if ( ( $u >= 1000 || $u == 0 ) && ( $_ =~ /[[:alpha:]]/ && $_ ne "nobody" ) ) }'

Loosely explained: display “root” who has a UID of 0, display regular users (they will have UID’s of 1000 or higher), don’t display the “nobody” user, and don’t display the effective UID’s of system-level processes running with UID’s that don’t correspond to an entry in the /etc/passwd database. (The formatted Perl code in the above one-liner is provided at the end of this post.) The output will now look something like:

root
superman

As promised, the formatted Perl code:

for ( <> ) { # read STDIN line by line
 
   chomp; # remove line endings
 
   $u = ( getpwnam($_) )[2]; # get the numeric UID of the user
 
   print $_, "\n" if ( # output the username if...
 
      # ...the user is a "regular" user, or root...
      ( $u >= 1000 || $u == 0 ) &&
 
      # ...and as long as the user has a real name and it isn't "nobody"
      ( $_ =~ /[[:alpha:]]/ && $_ ne "nobody" )
   ) 
}

Final thoughts: this is terrible. Ubuntu has "broken" the w command (and its relatives). While it’s nice to know that you can still get the info you need by massaging it out of the ps command, this really is a dirty hack.

*There’s a dirty way to “hide” processes from the Linux/Unix process table.  There are feasible reasons to do this from time to time, but for the most part it’s only malicious software that does such a thing.  The ps command won’t show hidden processes.  If you want to guarantee that you can see all processes, take a look at the unhide utility.