Skip to content

Unix / Linux - Processes

A process is an instance of a running program. Every time you execute a command or run an application on a Unix-like system, one or more processes are created. The operating system manages these processes, allocating resources like CPU time and memory.

Each process is uniquely identified by a Process ID (PID), a non-negative integer. The system uses the PID to track and manage individual processes.

Processes also have a Parent Process ID (PPID), which is the PID of the process that created them. This forms a hierarchy of processes, ultimately tracing back to the initial system process (often called init or systemd with PID 1).

Running Processes: Foreground and Background

Section titled “Running Processes: Foreground and Background”

When you run a command, you can do so in two primary modes:

By default, commands run in the foreground. The shell waits for the process to complete before giving you back the prompt ($). While a foreground process is running, you generally cannot enter new commands in that terminal.

The process typically receives input from the keyboard (standard input) and sends output to the screen (standard output and standard error).

# This command runs in the foreground. The prompt won't return until it finishes.
$ sleep 10
# (Waits 10 seconds)
$

You can usually interrupt a foreground process by pressing Ctrl + C.

A background process runs independently of the shell. You get the command prompt back immediately, allowing you to run other commands while the background process continues its execution.

To run a command in the background, append an ampersand (&) to the end of the command line.

# Run the sleep command in the background
$ sleep 60 &
[1] 12345 # The shell reports the Job ID ([1]) and the PID (12345)
$ # Prompt returns immediately, sleep continues for 60 seconds

Background processes are disconnected from keyboard input. If they attempt to read from standard input, they will usually pause (become stopped). Their output still goes to the terminal unless redirected.

When a background job completes, the shell often prints a notification:

$ # (After 60 seconds)
[1]+ Done sleep 60

The ps (process status) command displays information about running processes. Its usage varies slightly between different Unix flavors, but common invocations exist.

Basic usage (shows processes associated with the current terminal):

$ ps
PID TTY TIME CMD
5678 pts/0 00:00:00 bash
12389 pts/0 00:00:00 ps

Common options for more comprehensive listings:

  • System V style: ps -ef (or ps -eF for extra detail)
  • -e: Show all processes.
  • -f: Full format listing (UID, PID, PPID, C, STIME, TTY, TIME, CMD).
  • BSD style: ps aux (or ps auxww for wider command output)
  • a: Show processes for all users.
  • u: User-oriented format (USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMAND).
  • x: Show processes not attached to a terminal (like daemons).

Example using System V style:

$ ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 09:00 ? 00:00:05 /sbin/init
root 2 0 0 09:00 ? 00:00:00 [kthreadd]
...
user 5678 5670 0 09:15 pts/0 00:00:00 /bin/bash
root 8901 1 0 09:20 ? 00:00:01 /usr/sbin/sshd -D
user 12345 5678 0 10:05 pts/0 00:00:00 sleep 60
user 12390 5678 0 10:06 pts/0 00:00:00 ps -ef

Key columns often include:

  • USER / UID: User running the process.
  • PID: Process ID.
  • PPID: Parent Process ID.
  • %CPU: CPU usage.
  • %MEM: Memory usage.
  • STIME / START: Start time.
  • TTY: Controlling terminal (? if none).
  • TIME: Accumulated CPU time.
  • CMD / COMMAND: The command being run.

Terminating processes is often necessary.

  • Ctrl + C: Sends an interrupt signal (SIGINT) to the foreground process, usually causing it to terminate.
  • kill PID: Sends a termination signal (SIGTERM, signal 15 by default) to the process with the specified PID. This is a polite request to terminate, allowing the process to clean up.
  • kill -9 PID or kill -SIGKILL PID: Sends the kill signal (SIGKILL, signal 9). This forces immediate termination and should be used as a last resort, as the process gets no chance to save data or clean up.
  • pkill process_name: Sends a signal (SIGTERM by default) to all processes matching the given name.
  • killall process_name: Similar to pkill, but exact behavior can vary slightly between systems. Often more strict about matching the exact process name.

Example: Find and terminate a sleep process.

# Start a sleep process in the background
$ sleep 300 &
[1] 13579
# Find its PID (assuming we didn't note it)
$ ps aux | grep 'sleep 300'
user 13579 0.0 0.0 1234 567 pts/0 S 10:15 0:00 sleep 300
user 13581 0.0 0.0 6789 1234 pts/0 S+ 10:15 0:00 grep sleep 300
# Send the default termination signal (SIGTERM)
$ kill 13579
# Check if it's gone (wait a moment)
$ ps aux | grep 'sleep 300'
# (Should only show the grep command itself now)
# If kill didn't work, force kill
# kill -9 13579
# Alternatively, using pkill:
$ pkill sleep
[1]+ Terminated sleep 300

You can generally only kill processes that you own, unless you are the root user.

Shells provide job control features to manage background and stopped processes within the current session.

  • jobs: Lists the jobs (background or stopped processes) started from the current shell, showing their job ID (e.g., [1], [2]) and status.
  • fg %job_id: Brings a background or stopped job to the foreground. Example: fg %1.
  • bg %job_id: Resumes a stopped job in the background. Example: bg %2.
  • Ctrl + Z: Suspends (stops) the current foreground process and puts it in the background. You can then use bg to resume it in the background or fg to resume it in the foreground.
# Start two jobs
$ sleep 100 &
[1] 14001
$ sleep 200 &
[2] 14002
# List jobs
$ jobs
[1]- Running sleep 100 &
[2]+ Running sleep 200 &
# Bring job 1 to the foreground
$ fg %1
sleep 100
# (Now sleep 100 is in the foreground. Press Ctrl+Z)
^Z
[1]+ Stopped sleep 100
# List jobs again
$ jobs
[1]+ Stopped sleep 100
[2]- Running sleep 200 &
# Resume job 1 in the background
$ bg %1
[1]+ sleep 100 &
# List jobs again
$ jobs
[1]- Running sleep 100 &
[2]+ Running sleep 200 &
  • Orphan Process: A process whose parent process has terminated. Orphaned processes are typically adopted by the init process (PID 1) or its modern equivalent (systemd).
  • Zombie Process (or Defunct Process): A process that has completed execution but still has an entry in the process table. This occurs because the parent process hasn’t yet read its child’s exit status. Zombies consume minimal resources (just the process table entry) but a large number can indicate a problem with the parent process.

Zombie processes usually appear with a Z status in ps output. You cannot kill a zombie process directly; you need to terminate its parent process or wait for the parent to correctly handle the child’s exit (reap it).

Daemons are processes that run in the background, detached from any terminal, and perform system tasks or provide services. Examples include web servers (httpd, nginx), database servers (mysqld), and the SSH server (sshd).

They are often started at boot time and run continuously. On modern Linux systems using systemd, these are typically managed as ‘services’ using the systemctl command (e.g., systemctl status sshd, systemctl start nginx). Traditionally, they might be managed via init scripts in /etc/init.d/.

The top command provides a dynamic, real-time view of running processes, sorted by CPU usage by default. It shows system summary information (load average, CPU states, memory usage) and a list of processes.

$ top

top is interactive; press h for help, q to quit, M to sort by memory, P to sort by CPU.

htop is a popular, enhanced alternative to top offering a more user-friendly interface with color, scrolling, easier sorting, and process killing capabilities. If not installed, you can often install it via your system’s package manager (e.g., sudo apt install htop or sudo yum install htop).

$ htop