Skip to main content

Overview

Power Guard (power_guard.sh) is a lightweight system monitoring script that scans for CPU-intensive processes and automatically terminates those exceeding a configurable threshold. It includes a whitelist feature to protect critical system processes.
This script is designed to prevent runaway processes from consuming excessive CPU resources, particularly useful on resource-constrained systems or when running long-running tasks.

Key Features

Automatic Process Management

Continuously monitors and terminates high-CPU processes automatically

Configurable CPU Threshold

Set custom CPU limit percentage to match your system requirements

System Process Protection

Whitelist critical system processes to prevent accidental termination

Graceful Termination

Uses SIGTERM (kill -15) for clean process shutdown

Configuration

The script uses two main configuration variables at the top of the file:

CPU_LIMIT

CPU_LIMIT
number
default:"30"
The maximum CPU usage percentage allowed before a process is terminated.Processes using more than this percentage will be killed (unless whitelisted).
power_guard.sh
CPU_LIMIT=30   # percent
Set CPU_LIMIT=50 for systems with occasional high-CPU tasks that should be allowed to complete.

WHITELIST

WHITELIST
string
default:"gnome-shell|Xorg|systemd|NetworkManager"
Pipe-separated regex pattern of process names that should never be killed.Critical system processes should always be included to prevent system instability.
power_guard.sh
WHITELIST="gnome-shell|Xorg|systemd|NetworkManager"
  • gnome-shell - GNOME desktop environment
  • Xorg - X Window System display server
  • systemd - System and service manager
  • NetworkManager - Network connection manager

Adding to the Whitelist

To protect additional processes, add them to the pipe-separated list:
Custom Whitelist
WHITELIST="gnome-shell|Xorg|systemd|NetworkManager|docker|postgres|nginx"
Be careful when modifying the whitelist. Removing essential system processes like systemd or Xorg could cause system instability or crashes.

How It Works

The script follows a simple but effective process:
1

Scan Processes

Uses ps -eo pid,comm,%cpu --sort=-%cpu to list all processes sorted by CPU usage (highest first)
2

Check CPU Usage

Iterates through each process and compares its CPU percentage to CPU_LIMIT
3

Apply Whitelist

Checks if the process name matches any pattern in the WHITELIST
4

Terminate Process

Sends SIGTERM (kill -15) to non-whitelisted processes exceeding the limit

Code Walkthrough

power_guard.sh
#!/usr/bin/env bash

CPU_LIMIT=30   # percent
WHITELIST="gnome-shell|Xorg|systemd|NetworkManager"

echo "Scanning for power goblins..."

ps -eo pid,comm,%cpu --sort=-%cpu | tail -n +2 | while read pid name cpu
do
  cpu_int=${cpu%.*}  # Strip decimal portion

  if [[ $cpu_int -gt $CPU_LIMIT ]]; then
    if [[ ! $name =~ $WHITELIST ]]; then
      echo "Killing $name (PID $pid) using $cpu% CPU"
      kill -15 $pid
    fi
  fi
done
  1. ps -eo pid,comm,%cpu --sort=-%cpu - Lists processes with PID, command name, and CPU usage, sorted descending
  2. tail -n +2 - Skips the header line from ps output
  3. cpu_int=${cpu%.*} - Removes decimal from CPU percentage for integer comparison
  4. [[ $cpu_int -gt $CPU_LIMIT ]] - Tests if CPU exceeds limit
  5. [[ ! $name =~ $WHITELIST ]] - Tests if process is NOT in whitelist (regex match)
  6. kill -15 $pid - Sends SIGTERM for graceful shutdown

Usage

One-Time Scan

Run the script once to scan and kill high-CPU processes:
./power_guard.sh
Output:
Scanning for power goblins...
Killing chrome (PID 12345) using 87% CPU
Killing ffmpeg (PID 12346) using 45% CPU

Continuous Monitoring

For continuous monitoring, run the script in a loop with a delay:
while true; do
  ./power_guard.sh
  sleep 60  # Check every 60 seconds
done

Background Monitoring

Run as a background daemon:
while true; do
  ./power_guard.sh
  sleep 60
done &
To stop background monitoring:
# Find the process
ps aux | grep power_guard

# Kill it
kill <PID>

Systemd Service

For automatic monitoring on system boot, create a systemd service:
[Unit]
Description=Power Guard CPU Monitor
After=network.target

[Service]
Type=simple
ExecStart=/bin/bash -c 'while true; do /path/to/power_guard.sh; sleep 60; done'
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Signal Types

The script uses kill -15 (SIGTERM) for graceful termination:
  • SIGTERM (15) - Graceful termination (default, used by script)
    • Allows process to clean up resources
    • Process can catch and handle the signal
    • Recommended for normal process termination
  • SIGKILL (9) - Forceful termination (not used)
    • Immediately terminates process
    • Cannot be caught or handled
    • May leave resources in inconsistent state
    • Use only when SIGTERM fails
If you need more aggressive termination, you can modify the script to use kill -9 $pid (SIGKILL) instead of kill -15 $pid, but this should be a last resort.

Customization Examples

Protect Browser Processes

CPU_LIMIT=40
WHITELIST="gnome-shell|Xorg|systemd|NetworkManager|chrome|firefox"

Aggressive Power Saving

CPU_LIMIT=15
WHITELIST="gnome-shell|Xorg|systemd|NetworkManager"

Development Workstation

CPU_LIMIT=50
WHITELIST="gnome-shell|Xorg|systemd|NetworkManager|node|npm|docker|code"

Server Environment

CPU_LIMIT=25
WHITELIST="systemd|sshd|nginx|postgres|redis|docker"

Logging Enhancement

Add logging to track killed processes:
Enhanced Version
#!/usr/bin/env bash

CPU_LIMIT=30
WHITELIST="gnome-shell|Xorg|systemd|NetworkManager"
LOG_FILE="/var/log/power_guard.log"

echo "$(date): Scanning for power goblins..." | tee -a "$LOG_FILE"

ps -eo pid,comm,%cpu --sort=-%cpu | tail -n +2 | while read pid name cpu
do
  cpu_int=${cpu%.*}

  if [[ $cpu_int -gt $CPU_LIMIT ]]; then
    if [[ ! $name =~ $WHITELIST ]]; then
      msg="$(date): Killing $name (PID $pid) using $cpu% CPU"
      echo "$msg" | tee -a "$LOG_FILE"
      kill -15 $pid
    fi
  fi
done

Use Cases

Development Machines

Prevent runaway test processes or build tools from freezing your system

Shared Servers

Enforce fair resource usage among multiple users

CI/CD Runners

Prevent stuck build jobs from consuming resources indefinitely

Resource-Limited Systems

Maximize availability on VMs or containers with limited CPU

Limitations and Considerations

Important Considerations:
  • The script terminates processes immediately without confirmation
  • Legitimate high-CPU tasks (video encoding, compilation) will be killed
  • One-time scan only; doesn’t prevent processes from spawning again
  • Requires appropriate permissions to kill processes (may need sudo)
For legitimate high-CPU workloads, either:
  1. Add them to the WHITELIST
  2. Temporarily increase CPU_LIMIT
  3. Stop the monitoring script during the task

Troubleshooting

Permission Denied

If you see “Operation not permitted”:
Killing chrome (PID 12345) using 87% CPU
kill: (12345): Operation not permitted
Run with sudo:
sudo ./power_guard.sh

Process Keeps Restarting

If a killed process immediately restarts:
  1. Find the parent process or service manager
  2. Stop the service/parent instead:
sudo systemctl stop service-name

Whitelist Not Working

Ensure the process name matches exactly:
# Check exact process name
ps -eo comm | grep -i process-name

# Add to whitelist with correct name
WHITELIST="...|exact-process-name"

Script Template

Use the standardized template for creating similar monitoring scripts

GDrive Ingest

Another example of a well-structured bash script with progress monitoring

Build docs developers (and LLMs) love