I came across a scenario where I needed to stress test some new servers CPU and didn’t want to install any program to do it so I wrote a script to stress test CPU’s.
Features:
-
Customizable duration: Set any positive integer duration with -t.
-
Customizable core count: Stress a specific number of cores with -c, up to the maximum available.
-
Quiet mode: Use -q for minimal output, ideal for scripting or automated runs.
-
Input validation: Checks for valid duration and core count, with clear error messages.
-
Verbose reporting: Logs start/end times, core count, PIDs, and a countdown timer (unless in quiet mode).
-
Reliable cleanup: Stores PIDs and uses kill -9 to ensure yes processes are terminated.
-
Cleanup verification: Checks for lingering yes processes and warns if any remain.
Options:
-
-t duration: Set duration in seconds (default: 30).
-
-c cores: Specify number of CPU cores to stress (default: all available cores, as detected by nproc).
-
-q: Quiet mode, suppresses detailed output (only shows warnings or errors).
How to use:
-
Save as max_cpu.sh.
-
Make executable: chmod +x max_cpu.sh.
-
Run with options, e.g.:
-
./max_cpu.sh (default: 30 seconds, all CPU cores, verbose output)
-
./max_cpu.sh -t 60 (run for 60 seconds)
-
./max_cpu.sh -t 45 -c 2 (run for 45 seconds, stress 2 cores)
-
./max_cpu.sh -t 20 -q (run for 20 seconds, minimal output)
-
Example output (verbose mode, ./max_cpu.sh -t 5 -c 2):
Starting CPU stress test at Fri May 30 22:25:47 NZST 2025
Using 2 CPU core(s) for 5 seconds
Launching 'yes' processes to max out CPU...
Started 'yes' process with PID 12345
Started 'yes' process with PID 12346
Running CPU at 100% for 5 seconds...
Time remaining: 5 seconds
Time remaining: 4 seconds
Time remaining: 3 seconds
Time remaining: 2 seconds
Time remaining: 1 seconds
Stopping 'yes' processes...
Terminated process with PID 12345
Terminated process with PID 12346
All 'yes' processes terminated successfully
CPU stress test completed at Fri May 30 22:25:52 NZST 2025
Example output (quiet mode, ./max_cpu.sh -t 5 -q):
All 'yes' processes terminated successfully
Script:
#!/bin/bash
# Default values
DURATION=30
CORES=$(nproc)
VERBOSE=1 # 1 for verbose output, 0 for minimal
# Function to display usage
usage() {
echo "Usage: $0 [-t duration] [-c cores] [-q]"
echo " -t duration: Duration in seconds (default: 30)"
echo " -c cores: Number of CPU cores to stress (default: all, $CORES)"
echo " -q: Quiet mode (minimal output)"
exit 1
}
# Parse command-line options
while getopts "t:c:q" opt; do
case $opt in
t) DURATION=$OPTARG ;;
c) CORES=$OPTARG ;;
q) VERBOSE=0 ;;
*) usage ;;
esac
done
# Validate inputs
if ! [[ "$DURATION" =~ ^[0-9]+$ ]] || [ "$DURATION" -le 0 ]; then
echo "Error: Duration must be a positive integer"
usage
fi
if ! [[ "$CORES" =~ ^[0-9]+$ ]] || [ "$CORES" -le 0 ] || [ "$CORES" -gt "$(nproc)" ]; then
echo "Error: Number of cores must be a positive integer up to $(nproc)"
usage
fi
# Function to log messages (respects verbose mode)
log() {
if [ "$VERBOSE" -eq 1 ]; then
echo "$1"
fi
}
log "Starting CPU stress test at $(date)"
log "Using $CORES CPU core(s) for $DURATION seconds"
# Array to store process IDs
pids=()
# Start 'yes' processes for specified number of cores
log "Launching 'yes' processes to max out CPU..."
for i in $(seq $CORES); do
yes > /dev/null &
pids+=($!)
log "Started 'yes' process with PID ${pids[$i-1]}"
done
# Wait for specified duration, showing progress if verbose
if [ "$VERBOSE" -eq 1 ]; then
log "Running CPU at 100% for $DURATION seconds..."
for ((i=$DURATION; i>0; i--)); do
echo "Time remaining: $i seconds"
sleep 1
done
else
sleep $DURATION
fi
# Terminate all 'yes' processes
log "Stopping 'yes' processes..."
for pid in "${pids[@]}"; do
kill -9 "$pid" 2>/dev/null
log "Terminated process with PID $pid"
done
# Wait briefly to ensure cleanup
wait 2>/dev/null
# Verify no 'yes' processes remain
if ! pgrep -x "yes" > /dev/null; then
log "All 'yes' processes terminated successfully"
else
echo "Warning: Some 'yes' processes may still be running. Run 'sudo killall -9 yes' manually."
fi
log "CPU stress test completed at $(date)"