What is a Process?
A process is a running instance of a program. Each process gets a unique PID (Process ID) and runs with the permissions of the user who started it (or the system).
# Every process has a PID
$ echo $$
12345Viewing Processes
ps — Process Snapshot
# Show all processes (BSD style — most common)
$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 16896 13792 ? Ss 08:00 0:02 /sbin/init
root 234 0.0 0.1 9824 5632 ? S 08:00 0:00 [kthreadd]
root 456 0.0 0.0 0 0 ? I< 08:00 0:00 [kworker/0:1H]
admin 1234 0.3 1.2 345600 98700 ? Ss 09:05 0:12 nginx: worker
admin 1235 0.1 0.8 234560 65400 ? S 09:05 0:05 nginx: worker
root 1567 0.0 0.5 67800 28400 ? Ss 08:00 0:01 /usr/sbin/sshdColumn meanings:
| Column | Meaning |
|---|---|
USER | Owner of the process |
PID | Process ID (unique identifier) |
%CPU | CPU usage percentage |
%MEM | Memory usage percentage |
VSZ | Virtual memory size (KB) |
RSS | Physical memory resident (KB) |
TTY | Controlling terminal (? = no terminal) |
STAT | Process state |
START | When process started |
TIME | Cumulative CPU time |
COMMAND | Command that started the process |
Process States (STAT column):
| State | Meaning |
|---|---|
R | Running or runnable |
S | Sleeping (interruptible) |
D | Uninterruptible sleep (usually I/O) |
Z | Zombie (terminated but not reaped) |
T | Stopped (suspended) |
s | Session leader |
+ | Foreground process group |
# Show processes for current user
$ ps -u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
# Show process tree (see parent-child relationships)
$ ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 08:00 ? 00:00:02 /sbin/init
root 234 1 0 08:00 ? 00:00:00 [kthreadd]
root 456 2 0 08:00 ? 00:00:00 [kworker/0:1H]
admin 1234 1567 0 09:05 ? 00:00:12 nginx: workertop — Interactive Process Monitor
$ top
top - 10:30:15 up 45 days, 3:21, 2 users, load average: 0.52, 0.58, 0.59
Tasks: 127 total, 1 running, 125 sleeping, 0 stopped, 1 zombie
%Cpu(s): 5.2 us, 1.3 sy, 0.0 ni, 92.5 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
MiB Mem : 15800.8 total, 2048.0 free, 8192.0 used, 5560.8 buff/cache
MiB Swap: 2048.0 total, 1024.0 free, 1024.0 used. 7560.0 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1234 admin 20 0 345600 98700 28400 S 2.1 0.6 0:12.34 nginx
2345 root 20 0 9824 5632 3456 S 0.1 0.0 0:00.12 kworker/0:1
5678 admin 20 0 56700 23400 12300 S 0.0 0.1 0:01.23 dockerInteractive commands within top:
| Key | Action |
|---|---|
1 | Toggle per-CPU breakdown |
M | Sort by memory |
P | Sort by CPU |
T | Sort by time |
k | Kill a process (prompts for PID) |
r | Renice a process |
u | Filter by user |
f | Configure displayed fields |
q | Quit |
htop — Enhanced Interactive Monitor
# Install htop
$ sudo apt install htop -y
# Run htop
$ htophtop provides color-coded bars, mouse support, tree views, and easier signal sending than top.
Finding Specific Processes
pgrep — Find by Name
# Find PID of nginx processes
$ pgrep nginx
1234
1235
1236
# Show process name along with PID
$ pgrep -l nginx
1234 nginx: worker
1235 nginx: worker
1236 nginx: master
# Find processes by user
$ pgrep -u admin
1234
1235
5678pidof — Get PID of Running Program
# Get PID of sshd
$ pidof sshd
1567Searching with ps and grep
# Find nginx processes
$ ps aux | grep nginx
admin 1234 0.3 1.2 345600 98700 ? Ss 09:05 0:12 nginx: worker
admin 1235 0.1 0.8 234560 65400 ? S 09:05 0:05 nginx: worker
root 1567 0.0 0.5 67800 28400 ? Ss 08:00 0:01 nginx: master
# Exclude grep itself from results
$ ps aux | grep nginx | grep -v grepProcess Signals and Termination
Every process responds to signals — numbered messages sent by the kernel or other processes.
Common Signals
| Signal | Number | Name | Effect |
|---|---|---|---|
SIGTERM | 15 | Terminate | Graceful shutdown (clean up first) |
SIGINT | 2 | Interrupt | Same as pressing Ctrl+C |
SIGKILL | 9 | Kill | Force kill immediately (no cleanup) |
SIGSTOP | 19 | Stop | Suspend process |
SIGCONT | 18 | Continue | Resume a stopped process |
SIGHUP | 1 | Hangup | Reload configuration |
kill — Send Signal to Process
# Graceful termination (SIGTERM) — preferred first approach
$ kill 1234
# Force kill (SIGKILL) — when process is hung
$ kill -9 1234
# or
$ kill -SIGKILL 1234
# Send specific signal
$ kill -SIGTERM 1234
# Kill by process name (requires pkill)
$ pkill nginx # SIGTERM by default
$ pkill -9 nginx # SIGKILL
# Kill all processes matching pattern
$ killall nginxkillall — Kill by Process Name
# Kill all nginx processes
$ sudo killall nginx
# Kill with specific signal
$ sudo killall -9 nginxkill -9 (SIGKILL) should be your last resort. SIGTERM allows the process to close files, flush buffers, and terminate cleanly. A process killed with SIGKILL may leave temporary files or corrupt data.pkill — Kill by Name (Advanced)
# Kill processes matching pattern
$ pkill -f "python.*worker" # Kills python processes with "worker" in command
# Kill processes owned by specific user
$ sudo pkill -u alice
# Kill only processes in specific group
$ sudo pkill -G developersProcess Priority — nice and renice
Linux scheduler gives each process a nice value from -20 (highest priority) to +19 (lowest priority).
# Run a low-priority task (nice value of 10)
$ nice -n 10 ./backup.sh &
# Run a high-priority task (nice value of -10, requires root)
$ sudo nice -n -10 ./realtime-app &
# Change priority of already-running process
$ renice -n 5 -p 1234
1234: old priority 0, new priority 5
# Change priority for all processes by a user
$ sudo renice -n 10 -u alice# Check nice value in ps output
$ ps -eo pid,ni,cmd
PID NI CMD
1 0 /sbin/init
1234 0 nginx: master
1235 0 nginx: worker
5678 10 backup.shBackground and Foreground Jobs
# Run command in background
$ ./long-running-script.sh &
# Bring background job to foreground
$ fg
# Put running process in background (while running)
# Press Ctrl+Z to suspend
^Z
[1]+ Stopped ./long-running-script.sh
# Resume in background
$ bg
# List background jobs
$ jobs
[1]+ Stopped ./long-running-script.sh
[2]- Running ./data-pipeline.sh &Quick Reference
| Task | Command |
|---|---|
| List all processes | ps aux |
| Process tree | ps -ef |
| Interactive monitor | top or htop |
| Find PID by name | pgrep name |
| Find by name (with cmd) | pgrep -l name |
| Kill by PID | kill PID |
| Force kill | kill -9 PID |
| Kill by name | pkill name |
| Kill all by name | killall name |
| Change priority | renice -n N -p PID |
| Run with priority | nice -n N command |
| Background job | command & |
| List jobs | jobs |
| Bring to fg | fg |
| Resume in bg | bg |
Practice Challenge
- Run
ps aux— how many processes are running on your system? - Find the PID of your shell (bash) using
echo $$ - Run
topand press1to see per-CPU breakdown — pressqto quit - Use
ps -efto find theinitprocess (PID 1) and its child processes - Run a long command in the background with
sleep 60 &, then usejobsto see it - Kill the background job using
kill %1(where 1 is the job number)