Ubuntu Server 18.04 – Showing running processes with the ps command

How to install Ubuntu Server 19.10

While managing our server, we’ll need to understand what processes are running and how to manage these processes. Later in this chapter, we’ll work through starting, stopping, and monitoring processes. But before we get to those concepts, we first need to be able to determine what is actually running on our server. The ps command allows us to do this.

When executed by itself, the ps command will show a list of processes run by the user that called the command:

The output of the ps command, when run as a normal user and with no options

In the example screenshot I provided, you can see that when I ran the ps command as my own user with no options, it showed me a list of processes that I am running as myself. In this case, I have a vim session open (running in the background), and in the last line, we also see ps itself, which is also included in the output. We haven’t gone through background processes yet, so don’t worry about how I backgrounded vim just yet.

On the left side of the output, you’ll see a number for each of the running processes. This is known as the Process ID (PID), which is what I’ll refer to it as from now on. Before we continue on, the PID is something that you really should be familiar with, so we may as well cover it right now.

Each process running on your server is assigned a PID, which differentiates it from other processes on your system. You may understand a process as vim, or top, or some other name. However, our server knows processes by their ID. When you open a program or start a process, it’s given a PID by the kernel. As you work on managing your server, you’ll find that the PID is useful to know, especially for the commands we’ll be covering in this very chapter. If you want to kill a misbehaving process, for example, a typical workflow would be for you to find the PID of that process and then reference that PID when you go to kill the process (which I’ll show you how to do in a later section). PIDs are actually more involved than just a number assigned to running processes, but for the purposes of this chapter, that’s the main purpose we’ll need to remember.

You can also use the pidof command to find the PID of a process if you know the name of it. For example, I showed you a screenshot of a vim process running with a PID of 4346. You might run the following command:

pidof vim 
The output will give you the PID(s) of the process without you having to use the ps command.

Continuing with the ps command, there are several useful options you can give the command in order to change the way in which it shows its output. If you use the a option, you’ll see more information than you normally would:

ps a 
The output of the ps a command

With ps a, we’re seeing the same output as before, but with additional information, as well as column headings at the top. We now see a heading for the PID, TTY, STAT, TIME, and COMMAND. From this new output, you can see that the vim processes I have running are editing a file named testfile. This is great to know, because if I had more than one vim session open and one of them was misbehaving, I would probably want to know which one I specifically needed to stop.

The TTY, STAT, and TIME fields are new; we didn’t see those when we ran ps by itself. We saw the other fields, although we didn’t see a formal heading at the top. The PID column we’ve already covered, so I won’t go into any additional detail about that. The COMMAND field tells us the actual command being run, which is very useful if we either want to ensure we’re managing the correct process or to see what a particular user is running (I’ll demonstrate how to display processes for other users soon).

What may not be obvious at first are the STAT, TIME, and TTY fields. The STAT field gives us the status code of the process, which refers to which state the process is currently in. The state can be uninterruptible sleep (D), defunct (Z), stopped (T), interruptible sleep (S), and in the run queue (R). There is also paging (W), but that is not used anymore, so there’s no need to cover it. Interruptible sleep means that the program is idle: it’s waiting for input in order to awaken. Uninterruptible sleep is a state in which a process is generally waiting on input and cannot handle additional signals (we’ll briefly talk about signals later on in this chapter). A defunct process (also referred to as a zombie process) has, for all intents and purposes, finished its job but is waiting on the parent to perform cleanup. Defunct processes aren’t actually running but remain in the process list and should normally close on their own. If such a process remains in the list indefinitely and doesn’t close, it can be a candidate for the kill command, which we will discuss later. A stopped process is generally a process that has been sent to the background, which will be discussed in the next section.

The TTY column tells us which TTY the process is attached to. A TTY refers to a Teletypewriter, which is a term used from a much different time period. In the past, a Teletypewriter would be used to electronically send signals to a typing device on the other end of a wire. Obviously, we don’t use machines like these nowadays, but the concept is similar from a virtual standpoint. On our server, we’re using our keyboard to send input to a device which then displays output to another device. In our case, the input device is our keyboard and the output device is our screen, which is either connected directly to our server or is located on our computer which is connected to our server over a service such as SSH. On a Linux system, processes run on a TTY, which is (for all intents and purposes) a Terminal that grabs input and manages that output, similar to a Teletypewriter in a virtual sense. A Terminal is our method of interacting with our server.

In the screenshot I provided, we have one process running on a TTY of tty1, and the other processes are running on pts/0. The tty we see is the actual Terminal device, and pts references a virtual (pseudo) Terminal device. Our server is actually able to run several tty sessions, typically one to seven. Each of these can be running their own programs and processes. To understand this better, try pressing Ctrl + Alt + any function key, from F1 through F7 (if you have a physical keyboard plugged into a physical server). Each time, you should see your screen cleared and then moved to another Terminal. Each of these terminals is independent of one another. Each of your function keys represents a specific TTY, so by pressing Ctrl + Alt + F6, you’re switching your display to TTY 6.

Essentially, you’re switching from TTY 1 through to TTY 7, with each being able to contain their own running processes. If you run ps a again, you’ll see any processes you start on those TTYs show up in the output as a tty session, such as tty2 or tty4. Processes that you start in a Terminal emulator will be given a designation of pts, because they’re not running in an actual TTY, but rather a Pseudo-TTY.

This was a long discussion for something that ends up being simple (TTY or pseudo-TTY), but with this knowledge you should be able to differentiate between a process running on the actual server or through a shell.

Continuing, let’s take a look at the TIME field of our ps command output. This field represents the total amount of time the CPU has been utilized for that particular process. However, the time is 0:00 for each of the processes in the screenshot I’ve provided. This may be confusing at first. In my case, the vim processes in particular have been running for about 15 minutes or so since I took the screenshot, and they still show 0:00 utilization time even now. Actually, this isn’t the amount of time the process has been running, but rather the amount of time the process has been actively engaging with the CPU. In the case of vim, each of these processes is just a buffer with a file open. For the sake of comparison, the Linux machine I’m writing this chapter on has a process ID of 759 with a time of 92:51. PID 759 belongs to my X server, which provides the foundation for my graphical user environment and windowing capabilities. However, this laptop currently has an uptime of 6 days and 22 hours as I type this, which is roughly equivalent to 166 hours, which is not the same amount of time that PID 759 is reporting for its TIME. Therefore, we can deduce that even though my laptop has been running 6 days straight, the X server has only utilized 92 hours and 51 minutes of actual CPU time. In summary, the TIME column refers to the amount of time a process needs the CPU to calculate something and is not necessarily equal to how long something has been running, or for how long a graphical process is showing on your screen.

Let’s continue on with the ps command and look at some additional options. First, let’s see what we get when we add the u option to our previous example, which gives us the following example command:

ps au
The output of the ps au command

When you run it, you should notice the difference from the ps a command right away. With this variation, you’ll see processes listed that are being run by your user ID, as well as other users. When I run it, I see processes listed in the output for my user (jay), as well as one for root. The u option will be a common option you’re likely to use, since most of the time while managing servers you’re probably more interested in keeping an eye on what kinds of shenanigans your users are getting themselves into. But perhaps the most common use of the ps command is the following variation:

ps aux 

With the x option added, we’re no longer limiting our output to processes within a TTY (either native or pseudo). The result is that we’ll see a lot more processes, including system-level processes, that are not tied to a process we started ourselves. Go ahead and try it. In practice, though, the ps aux command is most commonly used with grep to look for a particular process or string. For example, let’s say you want to see a list of all nginx worker processes. To do that, you may execute a command such as the following:

ps aux | grep nginx 

Here, we’re executing the ps aux command as before, but we’re piping the output into grep, where we’re looking only for lines of output that include the string nginx. In practice, this is the way I often use ps, as well as the way I’ve noticed many other administrators using it. With ps aux, we are able to see a lot more output, and then we can narrow that down with search criteria by piping into grep. However, if all we wanted to do was to show processes that have a particular string, we could also do the following:

ps u -C nginx 

Another useful variation of the ps command is to sort the output by sorting the processes using the most CPU first:

ps aux --sort=-pcpu 

Unfortunately, that command shows a lot of output, and we would have to scroll back to the top in order to see the top processes. Depending on your Terminal, you may not have the ability to scroll back very far (or at all), so the following command will narrow it down further:

ps aux --sort=-pcpu | head -n 5 

Now that is useful! With that example, I’m using the ps aux command with the --sort option, sorting by the percentage of CPU utilization (-pcpu). Then I’m piping the output into the head command, where I’m instructing it to show me only five lines (-n 5). Essentially, this is giving me a list of the top five processes that are using the most CPU. In fact, I can do the same but with the most-used memory instead:

ps aux --sort=-pmem | head -n 5 

If you want to determine which processes are misbehaving and using a non-ordinary amount of memory or CPU, those commands will help you narrow it down. The ps command is a very useful command for your admin toolbox. Feel free to experiment with it beyond the examples I’ve provided; you can consult the man pages for the ps command to learn even more tricks. In fact, the second section of the man page for ps (under examples) gives you even more neat examples to try out.

Comments are closed.