_____                   _             ___     _________  __
 |_   _|__ _ __ _ __ ___ (_)_ __   __ _| \ \   / / ____\ \/ /
   | |/ _ \ '__| '_ ` _ \| | '_ \ / _` | |\ \ / /|  _|  \  /
   | |  __/ |  | | | | | | | | | | (_| | | \ V / | |___ /  \
   |_|\___|_|  |_| |_| |_|_|_| |_|\__,_|_|  \_/  |_____/_/\_\
advanced14 min

Process Management: ps, top, kill Commands

What is a Process?

Every running program in Linux is a process. When you execute a terminal command, open an application, or start a service, the operating system creates a process for that program. Each process has a unique PID (Process ID) number and consumes system resources (CPU, memory, disk I/O). Process management is one of the most fundamental skills for system administrators and developers.

The Linux kernel organizes processes in a tree structure. The first process on the system, init or systemd (PID 1), is the ancestor of all other processes. Every process has a parent process, and new processes are created via the fork() system call. This hierarchical structure makes managing and monitoring processes straightforward.

Process States

  • Running (R): The process is actively running or waiting for CPU time.
  • Sleeping (S): The process is waiting for an event (e.g., user input or disk I/O).
  • Stopped (T): The process has been stopped (e.g., with Ctrl+Z).
  • Zombie (Z): The process has terminated but has not yet been cleaned up by its parent process.
  • Uninterruptible Sleep (D): The process is in uninterruptible sleep (usually waiting for I/O).

Listing Processes with the ps Command

The ps (process status) command takes a snapshot of current processes. It is not a dynamic monitoring tool; it shows the state at the moment the command is executed.

Basic Usage

# Show processes in the current terminal
$ ps
  PID TTY          TIME CMD
 1234 pts/0    00:00:00 bash
 5678 pts/0    00:00:00 ps

# List all processes in detail (BSD format)
$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY   STAT START   TIME COMMAND
root         1  0.0  0.1 169412 13296 ?     Ss   Mar01   0:05 /sbin/init
root         2  0.0  0.0      0     0 ?     S    Mar01   0:00 [kthreadd]
www-data  1521  0.2  1.5 456780 125432 ?    S    10:30   0:15 nginx: worker

# List all processes in full format (System V format)
$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Mar01 ?        00:00:05 /sbin/init
root         2     0  0 Mar01 ?        00:00:00 [kthreadd]

Filtering ps Output

# Search for a specific process by name
$ ps aux | grep nginx
www-data  1521  0.2  1.5 456780 125432 ?  S  10:30  0:15 nginx: worker
root      1520  0.0  0.1  65432   5432 ?  Ss 10:30  0:00 nginx: master

# List processes of a specific user
$ ps -u username

# Display the process tree
$ ps auxf
# or
$ pstree

# Top 10 processes by CPU usage
$ ps aux --sort=-%cpu | head -11

# Top 10 processes by memory usage
$ ps aux --sort=-%mem | head -11

# Show specific columns with custom format
$ ps -eo pid,ppid,user,%cpu,%mem,comm --sort=-%cpu | head -20

Dynamic Monitoring with top and htop

The top Command

top is an interactive tool that monitors processes in real time. When launched, it displays a continuously updating table with system metrics such as CPU and memory usage.

# Launch top
$ top

# Useful keys inside top:
# q     → Quit
# k     → Kill a process (asks for PID)
# M     → Sort by memory usage
# P     → Sort by CPU usage
# 1     → Show each CPU core separately
# h     → Help menu
# u     → Filter by a specific user

# Monitor processes of a specific user
$ top -u username

# Set update interval to 2 seconds
$ top -d 2

htop: Enhanced Process Monitoring

htop is a colorful and more user-friendly alternative to top. It offers mouse support, horizontal/vertical scrolling, and easy process management.

# Installing htop
$ sudo apt install htop    # Debian/Ubuntu
$ sudo yum install htop    # CentOS/RHEL

# Launch htop
$ htop

# Useful keys inside htop:
# F1    → Help
# F2    → Setup
# F3    → Search
# F4    → Filter
# F5    → Tree view
# F6    → Sort by
# F9    → Send signal (kill)
# F10   → Quit

Sending Signals with kill, killall, and pkill

In Linux, you can control process behavior by sending signals to them. Despite its name, the kill command is used not just for termination but to send various signals.

Important Signals

  • SIGTERM (15): The default signal. Asks the process to terminate gracefully. The process can perform cleanup before exiting.
  • SIGKILL (9): Forced termination. The process cannot catch or ignore this signal. Use as a last resort.
  • SIGHUP (1): Sent when a session closes. Many daemons use this signal to reload configuration.
  • SIGSTOP (19): Pauses the process. The process cannot block this signal.
  • SIGCONT (18): Resumes a paused process.
  • SIGINT (2): Keyboard interrupt signal (sent with Ctrl+C).

The kill Command

# Terminate with default signal (SIGTERM)
$ kill 1234

# Force terminate with SIGKILL
$ kill -9 1234
# or
$ kill -SIGKILL 1234

# Send SIGHUP (reload configuration)
$ kill -1 1234
# or
$ kill -HUP 1234

# List all available signals
$ kill -l

killall and pkill

# Terminate all processes by name
$ killall nginx

# Terminate all processes of a specific user
$ killall -u username

# Terminate processes by pattern matching with pkill
$ pkill -f "python script.py"

# Send SIGKILL with pkill
$ pkill -9 firefox

# Find process PIDs with pgrep (search version of pkill)
$ pgrep -a nginx
1520 nginx: master process
1521 nginx: worker process

Background Process Management

You can run commands in the background, pause them, and bring them to the foreground in the terminal. This feature is very useful for managing long-running operations.

# Start a command in the background
$ long-task.sh &
[1] 5678

# Pause a running command with Ctrl+Z
$ long-task.sh
^Z
[1]+  Stopped     long-task.sh

# List background jobs
$ jobs
[1]+  Stopped     long-task.sh
[2]-  Running     other-task.sh &

# Resume a stopped job in the background
$ bg %1

# Bring a background job to the foreground
$ fg %1

# nohup: Keep running even after terminal closes
$ nohup long-task.sh &
# Output is written to nohup.out

# Redirect nohup output to a custom file
$ nohup long-task.sh > /var/log/task.log 2>&1 &

Zombie Processes

When a process terminates but its parent process has not collected its exit status via the wait() system call, the process enters a "zombie" state. Zombie processes do not consume resources but occupy entries in the PID table. A large number of zombie processes indicates a bug in the parent process.

# Finding zombie processes
$ ps aux | grep 'Z'

# Count zombie processes
$ ps aux | awk '{if($8=="Z") print}' | wc -l

# Find the parent of a zombie process
$ ps -o ppid= -p 

# Attempt cleanup by sending SIGCHLD to the parent
$ kill -SIGCHLD 

Summary

Linux process management is one of the cornerstones of system administration. Taking snapshots of processes with ps, performing real-time monitoring with top and htop, sending signals with kill, killall, and pkill, managing background processes with &, bg, fg, jobs, and nohup — all of these skills will become an integral part of your daily workflow. A solid understanding of process states, the signal mechanism, and background management gives you a significant advantage in both server administration and development workflows.