Linux Disk Monitor Shell Script: Auto-Clean Logs When Space Is Low

linux disk monitor shell script

Keep your Linux server healthy with this disk monitor and cleanup shell script. It checks disk usage, automatically cleans old logs and temp files when space is low, and can send email alerts.

What this script does

  • Monitors disk usage on / (or any mount point)
  • Runs cleanup when usage exceeds a threshold (default 85%)
  • Cleans old /var/log files, systemd journal, and /tmp
  • Runs apt-get clean or dnf clean all to free package cache
  • Logs everything to /var/log/disk-cleanup.log
  • Optional email alerts via mail command

Prerequisites

  • Root or sudo access
  • df, find, journalctl (systemd)
  • Optional: mailutils for email alerts

Step 1: Install the script

sudo nano /usr/local/bin/disk-monitor-cleanup.sh
sudo chmod +x /usr/local/bin/disk-monitor-cleanup.sh

Step 2: Full script (scroll to read)

disk-monitor-cleanup.sh
#!/usr/bin/env bash
#===============================================================================
# disk-monitor-cleanup.sh
# Monitor disk usage and auto-clean logs/temp files when threshold is exceeded
# Tested on: AlmaLinux 9, Ubuntu 22.04, Debian 12
# Usage: ./disk-monitor-cleanup.sh
# Cron:  0 3 * * * /usr/local/bin/disk-monitor-cleanup.sh >> /var/log/disk-cleanup.log 2>&1
#===============================================================================

set -euo pipefail

# ---------- CONFIGURATION ----------
MOUNT_POINT="/"                 # partition to monitor
THRESHOLD=85                    # trigger cleanup when usage >= this %
LOG_RETENTION_DAYS=14           # delete rotated logs older than N days
JOURNAL_RETENTION_DAYS=7        # keep systemd journal for N days
TMP_RETENTION_DAYS=7            # delete /tmp files older than N days
CLEAN_PATHS=("/var/log" "/tmp") # extra paths to scan for old files

# Optional email alert (leave empty to skip)
ALERT_EMAIL="[email protected]"

LOG_FILE="/var/log/disk-cleanup.log"
LOG_PREFIX="[$(date '+%F %T')]"
# ----------------------------------

log() {
  echo "${LOG_PREFIX} $*" | tee -a "${LOG_FILE}"
}

get_usage() {
  df -P "${MOUNT_POINT}" | awk 'NR==2 {gsub(/%/,"",$5); print $5}'
}

get_avail_human() {
  df -hP "${MOUNT_POINT}" | awk 'NR==2 {print $4 " free of " $2}'
}

send_alert() {
  local subject="$1"
  local body="$2"
  if [[ -n "${ALERT_EMAIL}" ]] && command -v mail >/dev/null 2>&1; then
    echo "${body}" | mail -s "${subject}" "${ALERT_EMAIL}"
  fi
}

clean_old_logs() {
  log "Removing compressed/rotated logs older than ${LOG_RETENTION_DAYS} days in /var/log"
  find /var/log -type f \( -name "*.gz" -o -name "*.1" -o -name "*.old" \) \
    -mtime +"${LOG_RETENTION_DAYS}" -print -delete 2>/dev/null || true
}

clean_journal() {
  if command -v journalctl >/dev/null 2>&1; then
    log "Vacuum systemd journal to ${JOURNAL_RETENTION_DAYS} days"
    journalctl --vacuum-time="${JOURNAL_RETENTION_DAYS}d" >/dev/null 2>&1 || true
  fi
}

clean_tmp() {
  log "Removing files in /tmp older than ${TMP_RETENTION_DAYS} days"
  find /tmp -type f -atime +"${TMP_RETENTION_DAYS}" -print -delete 2>/dev/null || true
}

clean_custom_paths() {
  local path
  for path in "${CLEAN_PATHS[@]}"; do
    [[ -d "${path}" ]] || continue
    log "Cleaning stale files under ${path} (${LOG_RETENTION_DAYS}d+)"
    find "${path}" -type f -mtime +"${LOG_RETENTION_DAYS}" \
      ! -path "/var/log/disk-cleanup.log" -print -delete 2>/dev/null || true
  done
}

apt_clean() {
  if command -v apt-get >/dev/null 2>&1; then
    log "Running apt-get clean and autoremove"
    apt-get clean -y >/dev/null 2>&1 || true
    apt-get autoremove -y >/dev/null 2>&1 || true
  elif command -v dnf >/dev/null 2>&1; then
    log "Running dnf clean all"
    dnf clean all -y >/dev/null 2>&1 || true
  fi
}

BEFORE=$(get_usage)
log "Disk ${MOUNT_POINT} usage: ${BEFORE}% — $(get_avail_human)"

if (( BEFORE >= THRESHOLD )); then
  log "Threshold ${THRESHOLD}% reached — starting cleanup"
  send_alert "Disk alert on $(hostname -s)" "Usage ${BEFORE}% on ${MOUNT_POINT}. Cleanup started."

  clean_old_logs
  clean_journal
  clean_tmp
  clean_custom_paths
  apt_clean

  AFTER=$(get_usage)
  log "Cleanup finished — usage now ${AFTER}% — $(get_avail_human)"
  send_alert "Disk cleanup done on $(hostname -s)" "Usage was ${BEFORE}%, now ${AFTER}% on ${MOUNT_POINT}."
else
  log "Disk usage OK (below ${THRESHOLD}%) — no cleanup needed"
fi

exit 0

Scroll inside the box to read the full script.

Step 3: Configure settings

Edit the top of the script:

  • THRESHOLD=85 — start cleanup at this disk usage %
  • LOG_RETENTION_DAYS=14 — how long to keep old log files
  • JOURNAL_RETENTION_DAYS=7 — systemd journal retention
  • ALERT_EMAIL — your email for alerts (optional)
Linux disk monitor cleanup shell script terminal output
Disk monitor script freeing space on a Linux server

Step 4: Test manually

sudo /usr/local/bin/disk-monitor-cleanup.sh
sudo tail -20 /var/log/disk-cleanup.log

Step 5: Schedule with cron (daily at 3 AM)

sudo crontab -e

Add:

0 3 * * * /usr/local/bin/disk-monitor-cleanup.sh >> /var/log/disk-cleanup.log 2>&1

Check disk usage manually

df -h
du -sh /var/log/* | sort -hr | head
journalctl --disk-usage

Related tutorials

Terminal screenshot is an original illustration created for Gnome IT Solutions (blog.gnomeitsolutions.com).