_____ _ ___ _________ __ |_ _|__ _ __ _ __ ___ (_)_ __ __ _| \ \ / / ____\ \/ / | |/ _ \ '__| '_ ` _ \| | '_ \ / _` | |\ \ / /| _| \ / | | __/ | | | | | | | | | | | (_| | | \ V / | |___ / \ |_|\___|_| |_| |_| |_|_|_| |_|\__,_|_| \_/ |_____/_/\_\
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.
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.
# 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]
# 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
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 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
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.
# 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
# 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
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 &
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
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.