Skip to content
beginner Phase 2 · Linux Fundamentals

Process Management

List, monitor, and manage running processes using ps, top, htop, kill, and process priority adjustments.

45m
0 problems
Topic Progress 0%

Viewing Processes

Viewing Processes

ps Command

# List all processes for current user
ps aux

# Full format with nice output
ps -ef

# Filter specific processes
ps aux | grep nginx
ps aux | grep '[n]ginx'   # Avoids matching grep itself

# Show process tree
ps -ef --forest
pstree
pstree -p   # Include PIDs

# Show processes for a specific user
ps -u www-data

# Show specific columns
ps -eo pid,ppid,user,%cpu,%mem,cmd --sort=-%cpu | head -20

# Find parent of a process
ps -o ppid= -p 1234

# Show all threads of a process
ps -Lf -p 1234

top and htop

# Interactive process viewer
top

# Key top commands:
# P - sort by CPU
# M - sort by memory
# k - kill a process (enter PID)
# q - quit
# 1 - show per-CPU stats
# H - show threads
# c - show full command

# Non-interactive top (for scripts)
top -bn1 | head -20

# htop (enhanced top)
htop

# Filter by user in htop
htop -u www-data

# Sort by memory in htop
htop --sort-key=PERCENT_MEM

Process Information from /proc

# View process details
cat /proc/1234/status | head -20
cat /proc/1234/cmdline | tr '\0' ' '
echo
cat /proc/1234/environ | tr '\0' '\n' | head -10

# View open files for a process
ls -la /proc/1234/fd/ | head -20

# View memory map
cat /proc/1234/maps | head -10

# View network connections
cat /proc/1234/net/tcp

Other Useful Commands

# Real-time I/O monitoring
iotop

# Real-time network monitoring
nethogs          # Bandwidth per process
nload            # Network interface load

# List open files and sockets
lsof -p 1234
lsof -i :8080          # Who's using port 8080?
lsof +D /var/log/      # Who's using files in /var/log?

# Show process resource usage
time ls /var/log/
# real    0m0.003s
# user    0m0.001s
# sys     0m0.002s

# strace - trace system calls
strace -p 1234 -e trace=network   # Trace network calls
strace -c ls /tmp                  # Count system calls

Managing Processes

Managing Processes

Signals

# List all signals
kill -l

# Common signals:
# SIGHUP  (1)  - Reload configuration (daemon reload)
# SIGINT  (2)  - Interrupt (Ctrl+C)
# SIGQUIT (3)  - Quit with core dump
# SIGKILL (9)  - Force kill (unblockable)
# SIGTERM (15) - Graceful termination (default)
# SIGUSR1 (10) - User-defined signal 1
# SIGUSR2 (12) - User-defined signal 2
# SIGSTOP (19) - Pause process
# SIGCONT (18) - Resume paused process

Killing Processes

# Graceful shutdown (default signal: SIGTERM)
kill 1234
kill -15 1234

# Force kill (use only if graceful fails)
kill -9 1234
kill -KILL 1234

# Send SIGHUP (reload config, used by nginx, etc.)
kill -HUP 1234

# Kill all processes matching a name
pkill nginx
pkill -9 nginx    # Force kill all nginx processes

# Kill by pattern with more control
pgrep -f 'python.*server' | xargs kill

# Kill all background jobs in shell
kill $(jobs -p)

Process Priority

# Start with higher priority (lower nice value = higher priority)
# Nice values range from -20 (highest) to 19 (lowest)
sudo nice -n -10 /usr/local/bin/myapp

# Change priority of running process
renice -5 -p 1234          # Set to -5
sudo renice -10 -p 1234    # Need root for negative values

# View nice value
ps -eo pid,ni,cmd | grep nginx

# Start with specific scheduling policy
sudo chrt -f 50 /usr/local/bin/realtime-app   # FIFO, priority 50

Background and Foreground Jobs

# Run in background
mycommand &

# List background jobs
jobs -l

# Bring job to foreground
fg %1

# Send to background
bg %1

# Disown a job (remove from shell job list)
disown %1

# Run command immune to hangups
nohup mycommand &

# Run in a screen/tmux session
tmux new -d -s deploy 'mycommand'

Practical Examples

# Find and kill zombie processes
ps aux | awk '{if ($8=="Z") print $2, $11}'
# Kill parent of zombie
kill -9 $(ps -o ppid= -p <zombie_pid>)

# Find process using too much memory
ps aux --sort=-%mem | head -10

# Kill all processes using more than 1GB RSS
ps -eo pid,rss,cmd | awk '$2 > 1048576 {print $1}' | xargs kill

# Limit memory of a process at runtime (cgroups)
sudo cgcreate -g memory:mygroup
echo 536870912 | sudo tee /sys/fs/cgroup/memory/mygroup/memory.limit_in_bytes
sudo cgexec -g memory:mygroup mycommand

Systemd Services

Systemd Services

systemctl Basics

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

# Check service status
systemctl status nginx

# Start/stop/restart services
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx    # Reload config without downtime

# Enable/disable at boot
sudo systemctl enable nginx
sudo systemctl disable nginx

# Enable and start
sudo systemctl enable --now nginx

# Check if a service is running
systemctl is-active nginx
systemctl is-enabled nginx

Creating a Custom Service

# Create service file
sudo tee /etc/systemd/system/myapp.service << 'EOF'
[Unit]
Description=My Application
After=network.target
Wants=postgresql.service

[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/server
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
StartLimitBurst=3
StartLimitIntervalSec=60

# Environment
Environment=NODE_ENV=production
Environment=PORT=8080
EnvironmentFile=/opt/myapp/.env

# Security hardening
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/log/myapp /var/lib/myapp

# Resource limits
LimitNOFILE=65536
MemoryMax=1G
CPUQuota=200%

# Logging
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp

[Install]
WantedBy=multi-user.target
EOF

# Reload and enable
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp

Viewing Logs

# View service logs
journalctl -u nginx
journalctl -u nginx -f          # Follow (like tail -f)
journalctl -u nginx --since '1 hour ago'
journalctl -u nginx --since '2024-01-01' --until '2024-01-02'

# View all logs since last boot
journalctl -b

# View kernel messages
journalctl -k

# View logs for a specific PID
journalctl _PID=1234

# View logs by priority
journalctl -p err    # Only errors
journalctl -p warning..err

# Disk usage of journal
journalctl --disk-usage

# Vacuum old logs
sudo journalctl --vacuum-size=500M
sudo journalctl --vacuum-time=30d

Systemd Timers (Alternative to Cron)

# Create a timer
sudo tee /etc/systemd/system/backup.timer << 'EOF'
[Unit]
Description=Run backup daily

[Timer]
OnCalendar=daily
Persistent=true
RandomizedDelaySec=3600

[Install]
WantedBy=timers.target
EOF

# Create the matching service
sudo tee /etc/systemd/system/backup.service << 'EOF'
[Unit]
Description=Backup service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=root
EOF

# Enable and start timer
sudo systemctl daemon-reload
sudo systemctl enable backup.timer
sudo systemctl start backup.timer

# List timers
systemctl list-timers
systemctl list-timers --all

# Test the service manually
sudo systemctl start backup.service

Cron Jobs

Cron Jobs

Crontab Syntax

# ┌───── minute (0-59)
# │ ┌───── hour (0-23)
# │ │ ┌───── day of month (1-31)
# │ │ │ ┌───── month (1-12)
# │ │ │ │ ┌───── day of week (0-7, 0 and 7 = Sunday)
# * * * * * command

Crontab Commands

# Edit crontab
crontab -e

# List current crontab
crontab -l

# List another user's crontab
sudo crontab -u deploy -l

# Remove all cron jobs for current user
crontab -r

# Check cron logs
grep CRON /var/log/syslog
journalctl -u cron

Cron Examples

# Run every minute
* * * * * /usr/local/bin/check.sh

# Run every 5 minutes
*/5 * * * * /usr/local/bin/check.sh

# Run every hour at minute 0
0 * * * * /usr/local/bin/hourly.sh

# Run daily at 2:30 AM
30 2 * * * /usr/local/bin/daily.sh

# Run weekly (Sunday at 3 AM)
0 3 * * 0 /usr/local/bin/weekly.sh

# Run monthly (1st at 4 AM)
0 4 1 * * /usr/local/bin/monthly.sh

# Run Mon-Fri at 9 AM
0 9 * * 1-5 /usr/local/bin/workday.sh

# Run every 15 minutes, but only on weekdays
*/15 * * * 1-5 /usr/local/bin/workday-check.sh

# Run with specific environment
MAILTO=admin@example.com
PATH=/usr/local/bin:/usr/bin:/bin

0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

# Anacron alternative (for systems that reboot often)
# /etc/anacrontab:
# 1  5  daily.backup  /usr/local/bin/backup.sh
# 7  25 weekly.cleanup  /usr/local/bin/cleanup.sh

Complete Cron Example

# Edit crontab
crontab -e

# Add:
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MAILTO=ops@example.com

# System monitoring - every 5 minutes
*/5 * * * * /usr/local/scripts/monitor.sh >> /var/log/monitor.log 2>&1

# Log rotation - daily at 1 AM
0 1 * * * /usr/sbin/logrotate /etc/logrotate.conf

# Database backup - daily at 2 AM
0 2 * * * /usr/local/scripts/db-backup.sh >> /var/log/db-backup.log 2>&1

# SSL certificate check - weekly
0 0 * * 0 /usr/local/scripts/check-ssl.sh

# Docker cleanup - Sunday at 3 AM
0 3 * * 0 /usr/bin/docker system prune -f >> /var/log/docker-prune.log 2>&1

# Reboot server - first of month at 4 AM (if needed)
0 4 1 * * /sbin/reboot