In this article, we continue our look at processes and go back to school for a moment, where we’ll pick up some of the basics that will help us increase our knowledge later. We will (very loosely) mimic the Process Tree output that we saw in the previous article with just the ps command. You might stumble across “forest” puns in manuals with regards to “trees” in case it’s confusing.
The “-e” switch is also equal to “-A” and will dutifully display ALL of the processes. We’re going to combine that with the “-j” option, which should give us a “jobs format.” I’m sorry to potentially give you more headaches, and I encourage to try a few of these of alternative options, but one small caveat would be that running “j” and “-j” gives different levels of information. The non-hyphenated version provides more output in this case.
We will also add the “-H” to display the hierarchical output. We can achieve this by running:
# ps -ejH
Or, in a parallel universe, alternatively, you could also use the following for vaguely similar results:
# ps axjf
Try it yourself. It’s far from identical to the “pstree” command seen previously, but there are similarities in the output due to the hierarchies.
Day to Day
It is easy to get overwhelmed by the level of detail that the ps command can provide. My favorite process command is:
# ps -ef
Using the “-e” option gives us a display of all the processes in the Process Table and the newly added “-f” switch gives us what’s known as full-format listing. Apparently, we can add “-L” to this concoction to offer us process thread information. I find this command very easy to remember around Christmas time.
# ps -eLf
Et voilà, as requested, two new columns NLWP (number of threads) and LWP (thread ID) are added to the now busy display.
If you only wanted to print the name of a process (which might be ideal for scripting), then you can separate the wheat from the chaff by using this command for process number “37”:
# ps -p 37 -o comm=
This is an option that I’ve used in the past a few times to check what command my terminal is currently responsible for. This is useful if you’re stressing your server or worrying your workstation with lots of extra load. The simple (non-hyphenated) “T” switch lets us view this.
# ps T
You can test this by running something unusual — like a for loop with a pause in it using “sleep” — or anything odd that stands out, such as this command.
# echo {1..999999} &
This simply runs a counter process in the background. And, when we run “ps T”, we can see processes associated with the terminal in question.
Built-In Features
Let’s look at a few other built-in basics of the pliable ps command.
You can reverse the output of a command with a non-hyphenated “N” switch, which stands for negate. Or, more precisely, from the manual, this lets you “Select all processes except those that fulfill the specified conditions. (negates the selection) Identical to –deselect.”
All is revealed in Listing 1. As you can see, there isn’t any mention of “ntp” except from our ps command.
# ps N ntp PID TTY STAT TIME COMMAND 1414 tty1 Ss+ 0:00 /sbin/mingetty /dev/tty1 1416 tty2 Ss+ 0:00 /sbin/mingetty /dev/tty2 1418 tty3 Ss+ 0:00 /sbin/mingetty /dev/tty3 1420 tty4 Ss+ 0:00 /sbin/mingetty /dev/tty4 1426 tty5 Ss+ 0:00 /sbin/mingetty /dev/tty5 1430 tty6 Ss+ 0:00 /sbin/mingetty /dev/tty6 9896 pts/1 S 0:00 sudo -i 9899 pts/1 S 0:00 -bash 10040 pts/1 R+ 0:00 ps N ntp
Listing 1: Demonstrates running processes without including “ntp” (note our “ps” command again being seen)
Imagine that you wanted to see the SSH activity as well as the Hardware Abstraction Layer daemon, “hald”. These are hardly related I agree, but you can never account for strange scenarios when it comes to computers.
The following command is a way of searching for a list of processes with a certain name, separated without a space and just a comma in this case.
# ps -C sshd,hald
If you need to check any processes that are run by a particular system group, you can do so with the following command:
# ps -G ntp
Compatibility
Although it’s not always the case, the modern ps command cleverly mitigates our migraine-inducing compatibility headaches by letting us run a simple command in several ways.
If, for example, you wanted to select a list of processes that belonged to the superuser, root, then you could achieve this with the following three commands (which admittedly display ever-so-slightly different outputs):
# ps -u root # ps U root # ps --user root
The above commands dutifully offer what’s known as the “EUID” or “effective ID” of a user but not the “real user ID”. In reality — no pun intended — every process actually has two user IDs, just to keep things simple. This also applies to groups, but let’s not worry about that.
Apparently, the kernel is most concerned with the “effective user ID” for activities such as writing to a file and whether a user is allowed to complete a request to do something that requires a privilege.
And, although this is required much of the time, there’s an important scenario within which the “real user ID” must be paid attention to. If someone or something wants to alter the owner of “effective user ID” on an already running process, then the kernel needs to check both the “real user ID” and the “effective user ID”.
Changing the ownership of a process is particularly useful if a new user wants to do essentially the same thing (like write to a file) as the existing owner does. Rather than duplicating the process (adding extra strain to the system and potentially introducing more security aspects to consider), we can avoid duplicating the process and simply reassign it.
What about after a user is finished with their short task? The answer is that we only temporarily give access and then swap it back to its original owner. If you want to reveal the somewhat elusive “real user IDs” then you can do so with system groups like this (which is the same as “-G”):
# ps --Group ntp
And, not surprisingly, we can do exactly the same thing for users as follows (we do this with “-U”):
# ps --User chrisbinnie
If you want to query a very specific Process ID (because you’ve spotted it in “top” or a script has complained about it), then for all intents and purposes, these commands all the do the same thing. I have included some output for comparison, because it’s short and easy to read in this case:
# ps -p 1248 PID TTY TIME CMD 1248 ? 00:00:08 ntpd # ps p 1248 PID TTY STAT TIME COMMAND 1248 ? Ss 0:08 ntpd -u ntp:ntp -p /var/run/ntpd.pid -g # ps --pid 1248 PID TTY TIME CMD 1248 ? 00:00:08 ntpd
If you’ve ever wondered about the efficiencies of a system, here’s something interesting. The kernel has to be able to tidy up when a user logs out (otherwise, there would be a plethora of useless processes clogging up the pipes) so Unix-like systems dutifully group processes into “sessions”. You can test for session IDs by using “–sid” or as below with “-s”:
# ps -s 1526
Note that a session can have an associated terminal (of “tty” or “Teletype” varieties) controlling it, however, only one process can be at running in the foreground. All these components are given numbers to keep the system nice and orderly. As a result, we have thread IDs, process IDs, process group IDs, and session IDs. And, here you were thinking that the ps command didn’t have much to do.
If you’re interested in reading a little more about sessions, this book excerpt is intriguing with sentences such as “Consequently, sessions are largely the business of shells. In fact, nothing else really cares about them.”
Here, I’ve provided a bit more detail about the powerful ps command and how it can help you discover information about your processes. There’s more to learn about parent processes, filesystems, and more in the next few articles.
Chris Binnie is a Technical Consultant with 20 years of Linux experience and a writer for Linux Magazine and Admin Magazine. His new book Linux Server Security: Hack and Defend teaches you how to launch sophisticated attacks, make your servers invisible and crack complex passwords.