Linux Command Line: Processes
What is a Process?
Technically speaking, a process is a series of interdependent operations carries out by a computer. Every time a program is launched or booted, a corresponding process is created.
Process management is at the heart of how modern operating systems manage multitasking operations. Without them, computers would only be able to run a single application at a time, making for a very limited user experience!
Unix organizes these processes by queueing them up, and having them waiting their turn at the CPU. Each process has a ranking, and a turn called a timeslice. Unix, and other related OS's sharing these features are known as time sharing systems. This is very much like a check-out line at the grocery store except the system is very rapid, with most programs taking fewer than a second to execute.
In this section, we'll go over how to examine what processes are doing, and how to interact with processes to stop or pause them as needed.
The very first process, init
Upon boot, the very first process to be run is
init (short for initialization).
After init is started, a series of shell scripts in /etc called init scripts are executed.
With each consecutive process, a unique identifier is given. Since
init is the first running process, it is given a PID of 1.
Types of Processes
Here are a few types of processes you should familiarize yourself with.
Most processes initialized by init are daemon programs (prounounced DEE-man). These processes just sit in the background and perform their tasks without any user interface.
Some example daemon processes are the mail and print daemons, which wait for some mail, or print job to come in.
Parent and Child Processes
Processes can launch other processes through appropriate system calls such as fork or spawn. What results is a parent-child process relationship.
If a process is run through the command line interface, or shell, the shell is the parent. Every process has a parent, except the
A zombie (or defunct) process arise when a child process is terminated, but its entry still lives in the process table. All memory and resources are released from the terminated child, and only its entry remains. until the parent process fetches status info for terminated child, this process is known as a zombie.
An orphan process arises when a process is still running, but its parent has died. They are adopted by init.
Now that we understand the concept of processes and learned a little bit of its jargon, let's see how we can view and control processes with shell commands.
Viewing Processes ps
We can easily view processes, using
ps (process status). This only displays the processes that run from the current terminal, so are limited.
$ ps PID TTY TIME CMD 2696 pts/0 0:00:00 bash 2745 pts/0 0:00:00 ps
At the most basic level, there are only four columns.
- Process identifier. Necessary for sending signals.
- Teletype. Refers to the terminal that is controlling the process. X programs and daemons don't have this, but text-mode programs do (eg. console, xterm or remote login session).
- Amount of CPU time consumed by the process. The higher it is, the more resources it's taking from the computer.
- The command that started the process.
Options with ps
As we'll see soon, the
ps command comes with a variety of options. Depending on where these options originated, you may or may not need dashes preceding the option letter.
- These come from an earlier Berkeley Software Distribution platform and require no dashes at all.
- These options are preceded by one dash, and are probably what you're most familiar with.
- GNU long
- As you're most likely familiar with, any GNU long options are preceded by two dashes (--).
More details with -ef
-f option prints full format listing, meaning it includes additional parameters. The
-A options displays all processes (including daemon).
$ ps -ef
UID PID PPID C STIME TTY TIME CMD root 1 0 3 11:14 ? 00:00:00 /sbin/init root 2 0 0 11:14 ? 00:00:00 [kthreadd] root 3 2 0 11:14 ? 00:00:00 [ksoftirqd/0] root 4 2 0 11:14 ? 00:00:00 [kworker/0:0] root 5 2 0 11:14 ? 00:00:00 [kworker/0:0H] root 6 2 1 11:14 ? 00:00:00 [kworker/u2:0] root 7 2 0 11:14 ? 00:00:00 [rcu_sched] root 8 2 0 11:14 ? 00:00:00 [rcuos/0] root 9 2 0 11:14 ? 00:00:00 [rcu_bh]
You'll notice that some processes have a
?. This means that they have no controlling terminals. Many of these are daemon processes.
Here are some more parameters listed, adding onto the list above.
- User ID
- Parent process identifier.
- CPU utilization.
- Time the process started.
Viewing user processes
To view all processes belonging to a user, use the
-u option, followed by the username. If you want to view more than one username, separate the names with a comma.
$ ps -u JohnDoePC # List all processes started by JohnDoePC
More details with aux
By attaching an
aux option (no hyphen), we can see even more details. The
a shows processes for all users, the
u displays the process's owner, and the
x shows processors not attached to a terminal.
w option shows the full command name, not just what fits on one line.
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.4 0.4 33772 2012 ? Ss 22:53 0:01 /sbin/init root 2 0.0 0.0 0 0 ? S 22:53 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? S 22:53 0:00 [ksoftirqd/0] root 4 0.0 0.0 0 0 ? S 22:53 0:00 [kworker/0:0] root 5 0.0 0.0 0 0 ? S< 22:53 0:00 [kworker/0:0H] root 6 0.0 0.0 0 0 ? S 22:53 0:00 [kworker/u2:0] root 7 0.2 0.0 0 0 ? S 22:53 0:00 [rcu_sched] root 8 0.0 0.0 0 0 ? S 22:53 0:00 [rcuos/0] root 9 0.0 0.0 0 0 ? S 22:53 0:00 [rcu_bh]
Here are some more variables that we see.
- User ID, or the owner of process.
- CPU usage as a percentage.
- Memory usage.
- Virtual memory size.
- Resident set size - amount of physical memory (RAM) the process is using (kb).
- Short for state. Reveals the current status of the process. See below for explanation.
- Time when processor started.
- Amount of CPU time process has acquired so far. Helpful for pinpointing runaway processes.
Here are some variables that go along with the
- Uninterruptible sleep - waiting for I/O device, such as a drive.
- Pages are locked into memory.
- Running, or ready to run.
- Sleeping, or waiting for user input.
- Defunct, or a zombie process, aka a child process that stopped, but has not been cleaned up by parent process
- High priority. Low niceness, meaning it takes up more resources.
- In the foreground process group.
- Low priority process. A nice process
- A session leader.
Inspecting current shell processes
To access the current shell's PID, use the shortcut
$$. This evaluates to the current shell's PID.
$ ps u $$ USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND JohnDoe 13030 0.0 0.0 27112 4092 pts/8 Ss 00:39 0:00 bash
Displaying process hierarchy
If you want to see where each process spawned from, we can use the
--forest option. You'll see that each child process branches out with tabs, signifying its origin
$ ps -AH ... 1 ? 00:00:01 init 299 ? 00:00:00 upstart-udev-br 304 ? 00:00:00 systemd-udevd 517 ? 00:00:00 upstart-socket- 774 ? 00:00:00 upstart-file-br 783 ? 00:00:00 rsyslogd 792 ? 00:00:03 dbus-daemon 805 ? 00:00:00 ModemManager 816 ? 00:00:00 systemd-logind 818 ? 00:00:00 bluetoothd 850 ? 00:00:01 avahi-daemon 852 ? 00:00:00 avahi-daemon ...
One drawback with using
ps is that it's static - we cannot see the changes while they occur. For a more dynamic view of currently running processes, we can use the
Dynamically Viewing Processes top
To see process information in real time, use the
top is a text-based program that shows all processes running and updates every few seconds so you can monitor them in real-time.
The view is separated into two halves - the top half is the system summary, while the bottom half is a table of processes sorted by the CPU activity.
top is sorted by CPU usage by default.
The system summary
Let's break down just the top half part of
top - 23:07:07 up 13 min, 2 users, load average: 0.02, 0.14, 0.14 Tasks: 160 total, 3 running, 157 sleeping, 0 stopped, 0 zombie %Cpu(s): 31.7 us, 8.9 sy, 0.0 ni, 59.1 id, 0.4 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem: 501496 total, 495492 used, 6004 free, 2568 buffers KiB Swap: 522236 total, 289316 used, 232920 free. 83052 cached Mem
First row, top:
- up - The amount of time since the machine was last booted.
- users - Number of users logged in.
- load average - Number of processes that are waiting their turn at the CPU in the last 1, 5 and 15 minutes. Any values < 1.0 means machine is not busy.
- Number of processes and their various process states.
- The task's share of the CPU time since the last screen update.
- us is the CPU being used for user processes. Processes outside the kernel itself.
- sy is how much is used for system processes (kernal).
- ni is how much is used by nice processes.
- id is the amount of CPU that is idle.
- wa is percentage waiting for I/O.
- How much physical RAM is being used.
- How much swap space is being used.
Checking system load average
Another way you can check load average without going through
top is with the
uptime command. You can use this command to quickly check if you have a runaway process that may have hung.
You can access the help screen with the
h key or
?. To quit, press
q. Here are some other commands you may use:
- Kill a process by inputting PID number.
- Change a processe's priority. Positive value decrease priority while a negative value increases. Default is 0 to begin with, and ranges are from -20 to 20.
- Display update rate (seconds).
- Sets display to sort by CPU usage.
- Change the display to sort by memory usage.
top, like many other commands, come with several options.
- -d delay
- Delay between updates - default is 5 seconds.
- -p pid
- Monitor specific processes.
- -n iter
- Tell top to display a certain number of updates, and then quit.
- Batch mode.
Backgrounds and Foregrounds jobs, bg, fg
Usually, when you start up a process, it takes over the terminal. These processes are thought of as running in the foreground. Let's now learn how to start a process in the background and how to move processes to and from the background/foreground.
Starting a Process in the Background
More often than not we'll want to launch a program right away into our foreground. However, if we plan to run a process that may take a long time, we can place it in the background so we can have still access to the command line interface. This way you can access the shell while it completes.
To start a process in the background, place an ampersand (
&) after it.
$ gedit &  2314
The output it places it called the job number, These identifiers are useful, as we'll later see when we use them to send signals.
Using jobs to check user run processes
To see the list of all processes within the current session (including those in the background), use the
jobs command. This is especially useful before logging out of a session to ensure that all processes that you've started have closed.
$ jobs + Running gedit &
The number in brackets is the job ID, with the term
Running describing its state.
job command is useful to make sure all the processes have been properly closed before logging out. If not, client programs may freeze up if a lot of programs are still running.
Moving a Process to and from the Background/Foreground
To move a process to the background from the foreground, use the
bg command and its job number.
$ bg 1
To move this back to the foreground, simply input the job number and use that as the argument for the
$ fg 1
Pausing a process kill, killall
To pause or stop a process, we can either use keyboard shortcuts or send a signal to our process. Let's look at the keyboard shortcuts first, then dive into what sending signals is all about.
Interrupting a Process
To interrupt a process, press ctrl+c.
This interrupts the program by sending it a
INT (interrupt) signal.
Pausing a Process
To pause a process, press ctrl+z. This sends the program a TSTP command (Terminal Stop).
This is especially useful if you want to pause a program and come back to it later. For example, we could have Python running, then press ctrl+z. This will place Python to the background. If you want to return to Python, simply type
fg %1, and you'll be back where you left off.
Stopping a process
Keyboard shortcuts are simply a convenient way to sending signals to jobs in our foreground.
As we have just seen, ctrl+c sends an
INT signal (for interrupt), and ctrl+z sends a
TSTP signal (terminal stop).
Besides sending an
INT (interrupt) or
TSTP (terminal stop) signal, there are many more signals that we can use with the
To use this command, specify a signal as the option, with the PID or the jobspec.
$ kill -s signal pid
If no signal is mentioned, the default signal is
Here is a list of Unix signals, which you may also see with the
kill -l command. When specifying the signal, you may either use the shortened word form, or its integer value. We've included an asterisk next to a signal to denote the most commonly used signals.
- 1 HUP*
- SIGHUP. Hang up.
- 2 INT
- Interrupt (same as ctrl+c). Terminates a program.
- 3 QUIT
- 9 KILL*
- Kill. This signal is not sent to the target program. Instead, the kernel immediately stops the process, which doesn't allow for a proper clean up.
- 11 SEGV
- Segmentation violation. Sent if program makes illegal use of memory, such as writing data where it's not permitted.
- 15 TERM*
- Terminate. The default signal sent by the KILL command.
- 18 CONT
- Continue. This restores a process after a STOP signal.
- 19 STOP
- Causes a process to pause without terminating. It is not send to the target process, like KILL.
- 20 TSTP
- Terminal stop. (same as ctrl+z).
- 28 WINCH
- Window change. A signal sent when the window changes size - some programs such as top and less respond by readjusting itself to fit into the new window.
Here are a few examples with the above signals.
$ kill -3 13569 # Quits out of process with PID 13569 $ kill -INT 1239 # Interrupts process with PID 1239.
Running processes persistently
Even without the
kill command, a process can be shutdown. For instance, if you
ssh into a computer, start up a process, then logout, a SIGHUP command will be sent out, and your program will be shut down.
To prevent your process to shutting down, precede the process invokation with the
$ nohup python3 MyRedditBot.py
Shutting down multiple processes
To shut down multiple processes, use the
killall command. This command uses a process' name instead of its PID. You may also place in the
-i option so that the terminal asks for confirmation before shutting down a process.
The following command will terminal all programs with the name
$ killall gedit
Changing process priorities
As mentioned before, each process takes up a certain amount of CPU time. For every moment the CPU is busy running one process, another process loses valuable running time.
As you can imagine, there will be some instances when you are under time constraints and want to prioritize one job over others. Or other times you'll want to push a process back so that it can run quietly in the background while you tend to other things. To control such priorities, we may launch a program with the
nice command, or modify a currently running process with
The term niceness comes from how "nice" the process is, in terms of how much CPU time it hogs. A nice process (as you would imagine) doesn't take too much CPU time and shares the CPU liberally with other processes.
This range of values goes from -20 to 20, where the lower the niceness, the more prioritized the process is. Thus, a "mean" process (one that hogs system resources) would have values close to -20, while a nicer process is closer to 20. The default niceness of any program is 10.
Syntax for nice
There are several ways you can call on nice:
$ nice -12 python longProgram.py $ nice -n 12 python longProgram.py $ nice --adjustment=12 python longProgram.py
As you can tell, we call nice, then specify any arguments before we input a command.
Syntax for renice
We can use the renice command to alter the priority of an already running process without disrupting its operation.
$ renice priority [[-p] pids] [[-g] pgrps] [[-u] users]
You may specify a process via its PID with the
-p option. If you want to change the priorities of all processes under a certain group or user, use the
$ renice 5 -p 21649 # Prioritizes the process with pid 21649 $ renice 19 -u SarahMarsh # Deprioritizes all processes belonging to user SarahMarsh