> ## Documentation Index
> Fetch the complete documentation index at: https://resources.devweekends.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Linux Process Management

> Manage Linux processes and services

# Linux Process Management

Learn to monitor, control, and manage processes in Linux. A process is simply a running program -- every command you type, every service running on your server, every background task is a process. Understanding processes is like understanding traffic flow in a city: you need to know what is running, what is stuck, and how to clear a jam.

***

## Viewing Processes

```bash theme={null}
# List all processes on the system
# a = show processes from all users
# u = display user/owner column
# x = include processes not attached to a terminal (daemons, services)
ps aux

# The columns that matter most:
# USER  PID  %CPU  %MEM  VSZ  RSS  STAT  START  TIME  COMMAND
# - PID: unique process ID (you need this to kill or inspect a process)
# - %CPU / %MEM: resource consumption at this instant
# - STAT: process state (S=sleeping, R=running, Z=zombie, D=uninterruptible sleep)
# - TIME: cumulative CPU time used (not wall clock time)

# Real-time process monitor (refreshes every few seconds)
top
# htop is the version you actually want -- color-coded, scrollable, mouse-friendly
htop  # Install with: sudo apt install htop

# Show the process tree -- see parent-child relationships
# This is invaluable for understanding which process spawned which
pstree
pstree -p  # Include PIDs in the tree

# Find a process by name (returns just the PID, great for scripting)
pgrep nginx
pgrep -a nginx  # Also show the full command line

# The classic approach -- but watch out for the grep process appearing in results
ps aux | grep nginx
ps aux | grep [n]ginx  # Bracket trick to exclude grep itself from results
```

<Tip>
  **When to use what**: Use `htop` for interactive exploration (what is eating my CPU right now?). Use `ps aux` for scripting and one-off checks. Use `pstree` when you need to understand process relationships, like which worker was spawned by which master process.
</Tip>

***

## Signals and Process Control

Killing a process is not always about force -- Linux uses **signals** to communicate with processes. Think of signals as tapping someone on the shoulder (polite) versus pulling the fire alarm (forceful).

```bash theme={null}
# Send the default SIGTERM (signal 15) -- asks the process to shut down gracefully
# The process gets a chance to close files, flush buffers, and clean up
kill PID

# SIGKILL (signal 9) -- forces immediate termination, no cleanup
# Use this only as a last resort when SIGTERM is ignored
kill -9 PID

# SIGHUP (signal 1) -- traditionally means "reload configuration"
# Many daemons (nginx, Apache) re-read their config files on SIGHUP
kill -HUP PID

# Kill by name instead of PID (convenient but be careful with naming collisions)
pkill nginx        # Sends SIGTERM to all processes named "nginx"
killall nginx      # Same idea, slightly different matching behavior

# Kill all processes owned by a user (nuclear option for runaway sessions)
pkill -u username
```

### Common Signals Reference

| Signal  | Number | Default Action               | Common Use                      |
| ------- | ------ | ---------------------------- | ------------------------------- |
| SIGHUP  | 1      | Terminate                    | Reload config files             |
| SIGINT  | 2      | Terminate                    | Ctrl+C in terminal              |
| SIGQUIT | 3      | Core dump                    | Ctrl+\ for debugging            |
| SIGKILL | 9      | Terminate (cannot be caught) | Force kill unresponsive process |
| SIGTERM | 15     | Terminate                    | Graceful shutdown (default)     |
| SIGSTOP | 19     | Stop (cannot be caught)      | Freeze a process                |
| SIGCONT | 18     | Continue                     | Resume a stopped process        |

<Warning>
  **Always try SIGTERM before SIGKILL.** SIGKILL (`kill -9`) does not let the process clean up -- it can leave behind lock files, corrupt data being written to disk, or leave child processes orphaned. Give SIGTERM a few seconds to work first.
</Warning>

***

## Background and Foreground Jobs

When you are working in a terminal, you often need to run something in the background while continuing other work. This is job control.

```bash theme={null}
# Run a command in the background (the & at the end)
./long-running-task.sh &

# List background jobs in the current shell session
jobs
# Output: [1]+  Running  ./long-running-task.sh &

# Bring background job #1 to the foreground (interactive again)
fg %1

# Suspend the current foreground process (does not kill it, just pauses)
# Press Ctrl+Z

# Resume a suspended process in the background
bg %1

# Detach a process from the terminal entirely so it survives logout
# nohup redirects output to nohup.out and ignores SIGHUP
nohup ./long-task.sh &

# Or use disown to detach an already-running background job
./long-task.sh &
disown %1
```

<Tip>
  **Production tip**: For long-running tasks on remote servers, use `tmux` or `screen` instead of `nohup`. They give you a persistent terminal session you can detach from and reattach to later, even after disconnecting SSH.
</Tip>

***

## Systemd Services

Modern Linux distributions use **systemd** to manage services (daemons). Systemd is the first process that starts (PID 1) and it manages the lifecycle of everything else. Think of it as the conductor of an orchestra -- it starts services in the right order, restarts them if they crash, and tracks their logs.

```bash theme={null}
# Start a service right now
sudo systemctl start nginx

# Stop a running service
sudo systemctl stop nginx

# Restart (stop + start) -- use when config changes require a fresh process
sudo systemctl restart nginx

# Reload -- ask the service to re-read its config without stopping
# Not all services support this, but it avoids downtime when they do
sudo systemctl reload nginx

# Enable a service to start automatically on boot
sudo systemctl enable nginx

# Disable auto-start on boot (does not stop the currently running service)
sudo systemctl disable nginx

# Check if a service is running, enabled, and see recent log output
sudo systemctl status nginx

# List all running services
systemctl list-units --type=service --state=running

# List all failed services (first thing to check when something is broken)
systemctl list-units --type=service --state=failed

# View logs for a specific service (systemd captures stdout/stderr automatically)
sudo journalctl -u nginx

# Follow logs in real time (like tail -f)
sudo journalctl -u nginx -f

# Show logs from the last boot only (filter out noise from previous boots)
sudo journalctl -u nginx -b

# Show logs from the last hour
sudo journalctl -u nginx --since "1 hour ago"
```

### Creating a Custom Service

When you deploy your own application, you write a unit file to let systemd manage it. This is one of the most practical skills in this chapter -- every production application should be managed by systemd rather than run manually in a `screen` or `tmux` session.

```ini theme={null}
# /etc/systemd/system/myapp.service
[Unit]
Description=My Application Server
# Start after networking is available (matters for web apps that bind to ports)
After=network.target
# Optional: also start after the database is ready
# Note: After= only controls ordering, not dependency. If postgresql fails to start,
# myapp still starts. Use Requires= for hard dependencies.
After=postgresql.service

[Service]
# Type=simple means systemd considers the service started as soon as the process launches
# Use Type=notify if your app signals readiness via sd_notify (more accurate health tracking)
# Use Type=forking if your app daemonizes itself (forks and parent exits)
Type=simple
User=deploy                    # Run as this user (never run app services as root)
Group=deploy
WorkingDirectory=/opt/myapp    # cd to this directory before starting
ExecStart=/opt/myapp/bin/server --port 8080
# Restart automatically if the process crashes (but not if it exits cleanly with code 0)
# Other options: always, on-abort, on-watchdog, no
Restart=on-failure
# Wait 5 seconds before restarting to avoid thrashing
# Without this, a crash-loop hammers your CPU and floods logs
RestartSec=5
# Cap restart attempts: if it crashes 5 times in 30 seconds, stop trying
StartLimitBurst=5
StartLimitIntervalSec=30
# Set environment variables for the service
Environment=NODE_ENV=production
# Or load environment from a file (better for secrets -- the file can be chmod 600)
# EnvironmentFile=/opt/myapp/.env

[Install]
# WantedBy=multi-user.target means "start this in normal multi-user mode"
# This is what makes 'systemctl enable' work (creates the symlink)
WantedBy=multi-user.target
```

```bash theme={null}
# After creating or modifying a unit file, reload systemd's configuration
# Without this, systemd does not see your changes
sudo systemctl daemon-reload

# Start the service AND enable it for boot in one command
sudo systemctl enable --now myapp

# Verify it is running
sudo systemctl status myapp

# If something is wrong, check the logs (systemd captures stdout and stderr)
sudo journalctl -u myapp -f
```

<Warning>
  **Common systemd pitfalls**: (1) Forgetting `daemon-reload` after editing a unit file -- systemd uses a cached copy and your changes are ignored. (2) Using `Type=simple` when the app forks -- systemd tracks the wrong PID and thinks the service died. (3) Not setting `Restart=on-failure` -- a single crash at 3 AM takes your service offline until a human notices. (4) Running services as root when they do not need root privileges -- use `User=` and `Group=` to run as a dedicated service account.
</Warning>

***

## Key Takeaways

* Every running program is a process with a PID, owner, and resource usage
* Use `htop` for interactive monitoring, `ps aux` for scripting
* Send SIGTERM first, SIGKILL only as a last resort
* Job control (`&`, `fg`, `bg`, `Ctrl+Z`) manages processes within your terminal session
* Systemd manages long-running services: start, stop, restart, and auto-start on boot
* Always check `systemctl status` and `journalctl -u` when debugging service failures
* Write custom unit files to let systemd manage your own applications

***

Next: [Linux Networking →](/courses/devops-tools/linux-networking)
