Heute mal ein Blogpost in Form einer Linux-Manpage 🙂 Mama sagt: „Ist halt scheiße fürs SEO, du Spacken.“ – aber was solls. Leben geht irgendwie weiter.
Blockpost
OS-CLEANUP-DEBIAN-SERVER(1) Beschmutzerhandbuch OS-CLEANUP-DEBIAN-SERVER(1)
NAME
os-cleanup-debian-server.sh - Wartungsskript zum Popoputzen von Debian-basierten Servern
ÜBERSICHT
os-cleanup-debian-server.sh
BESCHREIBUNG
Dieses einfach gestrickte Bash-Skript führt eine Systembereinigung auf Debian-basierten Servern durch. Es räumt veraltete Paketdaten
ab wie ein dickes Kind nachts mit tödlicher Präzision den Inhalt des Kühlschranks, löscht temporäre Dateien, begrenzt Systemd-Logs,
säubert - wie Léon der Profi seine Gegner - Container-Ressourcen und schreibt strukturierte Protokolle in eine Logdatei.
Ursprünglich aus einem altgedienten Script hervorgegangen, wurde es liebevoll generalüberholt, CO2-neutral durchgelüftet und auf Hochglanz poliert.
Das Script läuft auf meinen Servern als Cronjob und dient auch als Vorlage/Bestandteil eines Automatisierungs-Tasks.
PS: Da das Script neu aufgelegt wurde, ist es noch nicht ganz battle-tested. Vor allem der Task "System - Cleanup Temp Files" hat noch nicht
so viele Testdurchläufe.
FUNKTIONEN
cleanup_apt_packages
- Leert das APT-Cache-Verzeichnis (/var/cache/apt/archives) fast so schnell wie Behörden dein Konto.
- Entfernt (autoremove) nicht mehr benötigte Pakete – fast so flink wie Haustürdiebe eure Amazon-Pakete.
- Entfernt verwaiste Konfigurationspakete und schickt sie dahin, wo auch deine heroisch geplanten Neujahrsvorsätze immer landen > /dev/null.
- Frischt die Apt-Paketlisten fast so professionell und unauffällig auf wie manch Lobbyisten die Kaffeekasse der EU-Politiker im Hinterzimmer.
cleanup_journal_log_files
- Löscht bis auf die letzten 3 Tage die Systemd-Journal-Logfiles, damit wenigstens einige deiner IT-Sünden von letzter Woche gekonnt
unter den Tisch gekehrt werden :)
cleanup_tmp_files
- Entfernt Dateien und leere Verzeichnisse in /tmp und /var/tmp, sofern sie älter als 3 Tage und nicht in Benutzung sind (lsof-Prüfung).
cleanup_old_script_log_files
- Entfernt unter /var/log die von diesem hässlichen Skript erstellten Logdateien, die älter als ein 3 Tage Bart sind.
cleanup_container_resources
- Führt bei podman, docker und crictl ohne kulturelle Aneignung eine leichte und eine seichte Image-Bereinigung durch.
LOGGING
Die Ausgabe erfolgt actiongeladen sowohl im Terminal als auch in /var/log/os-cleanup-debian-server.sh.log.
Log-Level werden mit [INFO], [WARNING], [ERROR] (wie ein Hund den Baum) markiert. Farbige Ausgaben werden aus Respekt vor Diskriminierung und in Solidarität
mit monochromen Terminals nicht erstellt.
VORAUSSETZUNGEN
- Root[lichtviertel]-Rechte.
- Mindestens Volljährig oder im Beisein eines Erziehungsberechtigten :)
- Programme: bash, tee (am besten Schwarztee), find, lsof, apt-get, dpkg.
- Optional: podman, docker, crictl.
AUTOR
Hackspoiler - https://hackspoiler.de
VERSION
0.9.0 (erstellt am 30.01.2023, letzte Änderung 21.03.2025)
DATEIPFAD
/root/server-scripts/os-cleanup-debian-server.sh
INSTALLATION
curl -sSL https://codeberg.org/hackspoiler/root/src/branch/main/server-scripts/os-cleanup-debian-server.sh -o /root/server-scripts/os-cleanup-debian-server.sh
chmod +x /root/server-scripts/os-cleanup-debian-server.sh
NUTZUNG
./os-cleanup-debian-server.sh
Für automatische Ausführung via Cron z.B. jeden Montag um 03:00 Uhr Nackts (Serverzeit):
00 03 * * 1 root /root/server-scripts/os-cleanup-debian-server.sh
LIZENZ
Gerührt, nicht geschüttelt.
SIEHE AUCH
bash(1), apt-get(8), journalctl(1), find(1), lsof(8)
Debian-basiertes Server-Cleanup-Bash-Skript
#!/usr/bin/env bash
#==========================================================
# Author: Hackspoiler
# URL: https://hackspoiler.de
# Scriptname: os-cleanup-debian-server.sh
# Scriptpath: /root/server-scripts/
# Usage: ./os-cleanup-debian-server.sh
# Version: 0.9.0
# Date Creation: 30.01.2023
# Date Modification: 13.04.2025
# Used Packages: tee awk find lsof xargs
# Description: Cleanup a debian based server
#==========================================================
#==========================================================
# Check for root permissions
#==========================================================
if [[ "$EUID" -ne 0 ]]; then
echo "Script requires root permissions" >&2
exit 1
fi
#==========================================================
# Set Bash-Defaults
#==========================================================
set -o pipefail
set -o nounset
#==========================================================
# Les Variables
#==========================================================
SCRIPT_NAME=$(basename "$0" .sh)
LOG_FILE="/var/log/${SCRIPT_NAME}.log"
LOG_RETENTION_DAYS=3
#==========================================================
# Logging Setup
#==========================================================
exec > >(tee --append --ignore-interrupts "${LOG_FILE}") 2>&1
log() {
local LEVEL="$1"
local MESSAGE="$2"
local TIMESTAMP
TIMESTAMP=$(date +'%Y-%m-%d--%H-%M-%S')
if [[ "$LEVEL" == "ERROR" ]]; then
echo "${TIMESTAMP} [${LEVEL}] ${MESSAGE}" >&2
else
echo "${TIMESTAMP} [${LEVEL}] ${MESSAGE}"
fi
}
log_info() { log "INFO" "$1"; }
log_error() { log "ERROR" "$1"; }
log_warning() { log "WARNING" "$1"; }
#==========================================================
# Error handling
#==========================================================
tryrun() {
"$@"
local EXIT_CODE=$?
if [[ $EXIT_CODE -ne 0 ]]; then
log_warning "Command \"$*\" failed with exit code ${EXIT_CODE}, continuing..."
fi
}
#==========================================================
# Main
#==========================================================
# System - Cleanup Apt Packages
cleanup_apt_packages() {
local TASK_NAME="<===== Cleanup APT Packages.... =====>"
log_info "Start: ${TASK_NAME}"
export DEBIAN_FRONTEND=noninteractive
tryrun apt-get clean
tryrun apt-get autoclean
tryrun apt-get autoremove --purge --yes
tryrun dpkg --list | awk '/^rc/ {print $2}' | xargs --no-run-if-empty dpkg --purge
tryrun rm --force --verbose /var/lib/apt/lists/*
tryrun apt-get update -qq
}
# System - Cleanup Temp Files
cleanup_tmp_files() {
local TASK_NAME="<===== Cleanup Temp Files...... =====>"
log_info "Start: ${TASK_NAME}"
for TMPDIR in /tmp /var/tmp; do
# Delete files (only if not in use)
LC_ALL=C find "${TMPDIR}" -type f -mtime +${LOG_RETENTION_DAYS} -print0 | while IFS= read -r -d '' FILE; do
if ! lsof -- "${FILE}" &>/dev/null; then
rm --force --verbose -- "${FILE}" || log_warning "Could not delete ${FILE}"
else
log_info "File ${FILE} is dirty in use, skipping"
fi
done
# Delete directories (only if not in use)
LC_ALL=C find "${TMPDIR}" -type d -empty -mtime +${LOG_RETENTION_DAYS} -print0 | while IFS= read -r -d '' DIR; do
if ! lsof +d -- "${DIR}" &>/dev/null; then
rm --recursive --force --verbose -- "${DIR}" || log_warning "Could not delete ${DIR}"
else
log_info "Directory ${DIR} is dirty in use, skipping"
fi
done
done
}
# System - Cleanup Journal Logfiles
cleanup_journal_log_files() {
local TASK_NAME="<===== Cleanup Systemd Logfiles =====>"
log_info "Start: ${TASK_NAME}"
tryrun journalctl --vacuum-time="${LOG_RETENTION_DAYS}d" --vacuum-size=500M
}
# System - Cleanup Logs from this Script
cleanup_old_script_log_files() {
local TASK_NAME="<===== Cleanup Log Files....... =====>"
log_info "Start: ${TASK_NAME}"
tryrun find /var/log -type f -name "${SCRIPT_NAME}.log" -mtime +${LOG_RETENTION_DAYS} -delete
}
# App - Cleanup unused Podman/Docker/Kubernetes Images
cleanup_container_resources() {
local TASK_NAME="<===== Cleanup Container Shit =====>"
log_info "Start: ${TASK_NAME}"
if command -v podman &> /dev/null; then
tryrun podman image prune --force
fi
if command -v docker &> /dev/null; then
tryrun docker image prune --force
fi
if command -v crictl &> /dev/null; then
tryrun crictl rmi --prune
fi
}
# L'exécution
main() {
local INITIAL_SPACE=$(df -h / | awk 'NR==2 {print $4}')
log_info "Script gestartet: ${SCRIPT_NAME}"
cleanup_apt_packages
cleanup_journal_log_files
cleanup_tmp_files
cleanup_old_script_log_files
cleanup_container_resources
local FINAL_SPACE=$(df -h / | awk 'NR==2 {print $4}')
log_info "Initial Free Space: ${INITIAL_SPACE} - Final Free Space: ${FINAL_SPACE}"
}
main "$@"


