Warnung bei voller Platte

  Ralf Hersel   Lesezeit: 3 Minuten  🗪 9 Kommentare Auf Mastodon ansehen

Mit einem Shell-Skript könnt ihr die Belegung von Massenspeichern überwachen und euch warnen lassen, bevor diese zu voll werden.

warnung bei voller platte

Du möchtest nicht, dass der Massenspeicher auf deinem Computer vollläuft. Falls das passiert, zeigt sich ein Linux-System in einem Zustand zwischen "sehr bockig" und "ich mache hier gar nichts mehr". Vielleicht ist dieser Artikel überflüssig, weil aktuelle Distributionen bzw. Dateisysteme von sich aus warnen, wenn der Speicher knapp wird.

Hier ist ein kleines Shell-Skript, mit dem man eine (oder mehrere) Warnungen ausgeben kann, bevor es zu spät ist:

#!/bin/bash
THRESHOLD=80

df -h | grep '^/dev/' | while read line; do
    USAGE=$(echo $line | awk '{print $5}' | sed 's/%//')
    PART=$(echo $line | awk '{print $6}')

    if [ "$USAGE" -ge "$THRESHOLD" ]; then
        notify-send "Partition $PART is at ${USAGE}% on $(hostname)"
        zenity --info --text="Partition $PART is at ${USAGE}% on $(hostname)"
    fi
done

Was macht das Skript? Der Befehl df -h liefert die Daten für die Plattenauslastung:

df -h

Dateisystem           Größe Benutzt Verf. Verw% Eingehängt auf
dev                    7.7G       0  7.7G    0% /dev
run                    7.8G    1.9M  7.7G    1% /run
efivarfs               184K     95K   85K   53% /sys/firmware/efi/efivars
/dev/nvme0n1p2         458G     44G  391G   11% /
tmpfs                  7.8G    9.4M  7.7G    1% /dev/shm
tmpfs                  1.0M       0  1.0M    0% /run/credentials/systemd-journald.service
tmpfs                  7.8G     72M  7.7G    1% /tmp
/dev/nvme0n1p1         300M    296K  300M    1% /boot/efi
tmpfs                  1.6G    328K  1.6G    1% /run/user/1000
192.168.1.49:/mnt/nas  1.8T    220G  1.5T   13% /mnt/nas

Uns interessieren nur die eingehängten Dateisysteme, deren Namen mit dev oder /dev beginnen. Das EFI-Zeugs oder irgendwelche temporären Laufwerke lassen wir ausser Acht. Das wird von grep '^/dev/' erledigt. Dann holt das Skript für jede passende Zeile aus df -h die relevanten Spalten mit awk, nämlich die Belegung (USAGE) und den Mountpoint (PART). Für jede Zeile wird dann überprüft, ob sie über dem Limit von 80 % (THRESHOLD) liegt. Das sed 's/%//' entfernt das Prozentzeichen, weil wir für den Vergleich eine Zahl und keinen String brauchen.

Nun gibt es im Skript zwei Varianten für die Ausgabe der Warnung: notify und zenity. Es gibt noch x andere Möglichkeiten, die Warnung auszugeben, z. B. via E-Mail oder Messenger-Nachricht, doch das führt hier zu weit. Mit notify-send schickt man einen Text an das Benachrichtigungssystem der Desktopumgebung. Das sollte überall funktionieren, ohne etwas Weiteres installieren zu müssen; probiert es im Terminal vorher aus. Zenity muss installiert werden, falls ihr ein richtiges grafisches Warnfenster haben möchtet. Zu Zenity habe ich einen eigenen Artikel geschrieben; das Ding kann mehr, als hier gezeigt wird.

Um das Skript zu testen, macht ihr die Datei im Terminal oder Dateimanager ausführbar und startet sie im Terminal mit diesem Befehl: ./diskfull.sh (je nachdem, wie ihr das Skript genannt habt). Falls die Belegung der zu testenden Massenspeicher unter 80 % liegt, seht ihr dann gar nichts. Daher könnt ihr im Skript THRESHOLD=1 einstellen. Dann solltet ihr mehrere Notifikationen und Zenity-Fenster sehen:

Die Notifikation verschwindet nach ein paar Sekunden, während das Zenity-Fenster sichtbar bleibt, bis ihr auf OK klickt. Es ist Geschmackssache, für welche Variante ihr euch entscheidet.

Falls ihr nur ein Laufwerk überprüfen möchtet, könnt ihr den grep-Befehl im Skript spezifischer gestalten. Die Schleife würde ich beibehalten, weil ihr damit flexibler seid und später weitere Laufwerke für den Test hinzufügen könnt.

Sobald das Ergebnis euren Erwartungen entspricht, könnt ihr das Skript beim Booten automatisch starten lassen. Wie man das macht, hängt von eurer Desktopumgebung ab. Manche bieten dafür eine grafische Anwendung an, bei anderen, z. B. GNOME, muss man eine *.desktop-Datei im Verzeichnis ~/.config/autostart/ anlegen.

Titelbild: https://pixabay.com/photos/waterfall-fountain-nature-iron-3212901/

Quelle: https://www.tecmint.com/monitor-disk-usage-bash-script/

Tags

Massenspeicher, Plattenplatz, Skript, Benachrichtigung, Zenity

Col.Row
Geschrieben von Col.Row am 7. Oktober 2025 um 10:11

Moyen,

sehr interessant.

Vielleicht sollte man auch erwähnen, dass die meisten großen Desktopumgebungen bereits eine Prüfung für volllaufende Datenträger mitbringen. Die ist oft nur unpraktisch voreingestellt; vgl. [https://wiki.ubuntuusers.de/Howto/Datentr%C3%A4ger_voll/#Benachrichtigung-ueberpruefen(https://wiki.ubuntuusers.de/Howto/Datenträger voll/#Benachrichtigung überprüfen)]

Was man mit der mitgelieferten Überprüfung jedoch nicht kann, sind unterschiedliche Schwellenwerte. Auf meiner kleinen /boot sind 80% bereits kritisch, aber in meiner großen / erst bei 97% – Und das auch nur, weil kein weitere VM mehr aufgesetzt werden kann, sonst ginge noch mehr.

Ich habe diesen Artikel zum Anlass genommen meine Überwachung wiederholt zu überprüfen. Da muss ich versehentlich auf „Dieses Laufwerk von der Prüfung ausnehmen“ o. ä. gekommen sein. Jetzt habe ich ein Skript im autostart, dass dieses Versehen erkennt und zurücksetzt.

Und das hiesige Skript wird bei mir Basis für die Überwachung von /boot, falls ich mal ein Aufräumen vergessen haben sollte. Also Danke für den Artikel. Es zeigt sich mal wieder, dass man auch bereits erledigt geglaubte Themen noch mal durchdenken kann.

Ach, und wenn wir schon dabei sind: „notify-send“ ist bspw. bei Ubuntu nicht bei allen Geschmacksrichtungen dabei, sondern „gdbus“ – [https://wiki.ubuntuusers.de/Benachrichtigungsdienst/#Eigene-Nachrichten-ausgeben()]

Es lebe die Vielfalt! XD

kamome
Geschrieben von kamome am 7. Oktober 2025 um 13:13

Danke! Da zenity nicht immer das passende Werkzeug ist, lasse ich das im Script aussuchen (Auszug):

#!/usr/bin/env bash

[ ! '3' = "$#" ] && usage && exit 1

dlg_type="$1"
dlg_title="$2"
dlg_text="$3"

if [ 'KDE' = "$XDG_CURRENT_DESKTOP" -a $(command -v kdialog) ]; then
    gui_dlg=(kdialog --title $dlg_title)
elif [ 'GNOME' = "$XDG_CURRENT_DESKTOP" -a $(command -v zenity) ]; then
    gui_dlg=(zenity --title $dlg_title)
elif [ $(command -v kdialog) ]; then
    gui_dlg=(kdialog --title $dlg_title)
elif [ $(command -v zenity) ]; then
    gui_dlg=(zenity --title $dlg_title)
elif [ $(command -v yad) ]; then
    gui_dlg=(yad --title $dlg_title)
else
    exit 127
fi

if [ "message" = "$dlg_type" ]; then
    [ 'kdialog' = "$gui_dlg" ] && gui_dlg+=(--msgbox $dlg_text)
    [ 'zenity' = "$gui_dlg" ] && gui_dlg+=(--info --text $dlg_text)
    [ 'yad' = "$gui_dlg" ] && gui_dlg+=(--text-info --text $dlg_text)
fi

"${gui_dlg[@]}"

Vielfalt ist schön, aber nicht immer ;)

kamome
Geschrieben von kamome am 8. Oktober 2025 um 06:35

Und im allgemeinen Fall (wenn Titel und Text aus mehr als je einem Wort bestehen, also besser immer) müssten die Strings beim Hinzufügen zu den Arrays natürlich durch Quotes geschützt werden:

if [ 'KDE' = "$XDG_CURRENT_DESKTOP" -a $(command -v kdialog) ]; then
    gui_dlg=(kdialog --title "$dlg_title")
elif [ 'GNOME' = "$XDG_CURRENT_DESKTOP" -a $(command -v zenity) ]; then
    gui_dlg=(zenity --title "$dlg_title")
elif [ $(command -v kdialog) ]; then
    gui_dlg=(kdialog --title "$dlg_title")
elif [ $(command -v zenity) ]; then
    gui_dlg=(zenity --title "$dlg_title")
elif [ $(command -v yad) ]; then
    gui_dlg=(yad --title "$dlg_title")
else
    no_gui && exit 127
fi

if [ "message" = "$dlg_type" ]; then
    [ 'kdialog' = "$gui_dlg" ] && gui_dlg+=(--msgbox "$dlg_text")
    [ 'zenity' = "$gui_dlg" ] && gui_dlg+=(--info --text "$dlg_text")
    [ 'yad' = "$gui_dlg" ] && gui_dlg+=(--text-info --text "$dlg_text")
fi
Anonymous
Geschrieben von Anonymous am 7. Oktober 2025 um 14:42

Toller Beitrag! Besonders hilfreich für alle, die keine Desktopumgebung verwenden. Ich möchte jedoch ein paar ergänzende Anmerkungen teilen:

Bevor man sofort zu verschiedenen Tools wie grep, awk oder sed greift, lohnt es sich, zuerst zu prüfen, ob das genutzte Programm selbst alternative Ausgabeformate anbietet. Im Fall von df sind insbesondere die folgenden Optionen interessant (ich verwende bewusst die Langformen, damit sie auf den ersten Blick verständlich sind):

  • --type=
  • --exclude-type=
  • --output=source,size,used,pcent

Da man bei df leider die Überschriftszeile nicht ohne externe Tools entfernen kann, bietet sich hier ein anderes Werkzeug besser an: findmnt. Dieses erlaubt es, nach bestimmten Dateisystemen zu filtern und das Ausgabeformat sehr flexibel anzupassen – sogar so, dass es sich direkt für Shell-Skripte eignet, um Werte in Variablen zu speichern.

Einige besonders interessante Optionen von findmnt, die zum Ausprobieren einladen:

  • --df – imitiert die Ausgabe von df
  • --output – erlaubt die gezielte Auswahl von Spalten (alle verfügbaren Spalten zeigt --list-columns)
  • --pairs – formatiert die Ausgabe so, dass sie leicht in Shell-Variablen eingelesen werden kann
  • --real – zeigt nur reale Dateisysteme an
  • --types – filtert nach bestimmten Dateisystemtypen
  • --noheadings – unterdrückt die Ausgabe einer Kopfzeile. (nicht nötig bei --pairs)

Mit diesen vielseitigen Filter- und Formatierungsoptionen von findmnt – insbesondere in Kombination mit --pairs – kann man in den meisten Fällen auf externe Filtertools verzichten.

Ein weiterer Hinweis: Bei Copy-on-Write-Dateisystemen wie Btrfs würde man mit dieser Methode keine korrekte Erfassung der tatsächlichen Speicherbelegung erhalten. Hier ist eine andere Vorgehensweise erforderlich.

klausb
Geschrieben von klausb am 7. Oktober 2025 um 15:20

Eine ähnliche Aufgabe erledigt quota

nur ohne solchen netten Mitteilungen und meistens muss dann der Admin ran...

Lenny
Geschrieben von Lenny am 7. Oktober 2025 um 16:19

Man kann für einen User eine Speicherkapazität -Grenze (disk quota) einrichten und dann gibt es ebenfalls automatische Warnungen beim Erreichen oder dem Überschreiten der Grenze, inklusive einer Gandenfrist (grace period). Gibt es Gründe wieso der CLI Befehl "du" (disk usage) nicht verwendet wird?

Anonymous
Geschrieben von Anonymous am 7. Oktober 2025 um 20:04

Ich würde sagen, dass df oder auch findmnt schneller sind, weil sie eine Metadaten-Abfrage im Superblock des Dateisystems durchführen. Dadurch müssen nicht alle Objekte wie bei du rekursiv durchlaufen werden, was deutlich mehr Overhead verursacht.

du eignet sich gut, wenn man die Größe einzelner Dateien oder Ordner ermitteln möchte. Benötigt man jedoch Informationen, die das gesamte Dateisystem betreffen, kann man diese wesentlich schneller direkt aus dem Header (Superblock) auslesen.

awkawk
Geschrieben von awkawk am 9. Oktober 2025 um 10:33

Hallo Ralf. Nettes Script. Mit einem ganz ähnlichen Script habe ich früher als Sysadmin eine ganze Batterie von Unix- u. Linuxrechnern überwacht (>50). Mir leuchtet die Bedingung grep '^/dev/' nicht so ganz ein, zumal sie auch nicht zum abgedruckten df -h -Listing zu passen scheint. In meinen Scripten verwende ich grep '^/' das filtert genau die Parttitions heraus, die physikalisch geschrieben werden. Gemountete Verzeichnise (:) sollten es auch nicht in die Liste schaffen, da diese ja anderen Maschinen "gehören".

Vielen Dank. Bitte mehr Beiträge über scripting.

Gruß Karl.

Lars
Geschrieben von Lars am 15. Oktober 2025 um 10:31

Moin,

danke für die vielen Tipps.

Mein Senf: Wer noch zusätzliche fette HDDs besitzt, sollte mal mit tune2fs gucken, wie viele "Reserved block count" die Teile fressen. Per Default werden 5% einer Platte reserviert, was für /root echt notwendig ist, aber für HDD-Datengräber können hier noch etliche Gigabytes freigeschaufelt werden. IMHO reicht es auf solchen Platten 32000 Blöcke zu reservieren. Für eine 12TB Platte hieß das fast 600GB zusätzlichen freien Speicher (~150 Filme oder 75000 Bilder bei 8MB pro Bild oder 20VMs bei 30GB pro VM), denkt mal darüber nach.

JM2C.