Warn before the root drive fills up
This guide creates a script that checks the usage of the root partition. When usage reaches a threshold, the script sends a desktop notification. A systemd user timer runs the script every hour. Filling the boot drive completely can make the system unbootable, so this check helps you act early.
Threshold
Section titled “Threshold”Set the threshold in the script. A value between 75 and 90 percent is a good default. Use a lower value for small drives and a higher value for very large drives.
Requirements
Section titled “Requirements”libnotify, which provides thenotify-sendcommand used for desktop notifications.- A desktop session with a notification daemon. The breeze icons are optional, the script runs without them.
Create the script
Section titled “Create the script”-
Create the script in
~/.local/bin:Terminal window mkdir -p ~/.local/bintouch ~/.local/bin/check_disk.sh -
Open
~/.local/bin/check_disk.shin a text editor and paste the script below.#!/bin/bash## location of all check_disk related files## this script's location# cat ~/.local/bin/check_disk.sh## other check_disk related file locations## cat ~/.config/systemd/user/check_disk.service# cat ~/.config/systemd/user/check_disk.timer# cat ~/.local/state/check_disk.log# Delete old ~/.local/state/check_disk.log if it exceeds 1MB in size to conserve spacefind ~/.local/state/check_disk.log -size +1M -delete# Adjust threshold percentage to trigger alerts (75%-90% range recommended)# Temporarily lower the threshold to one (1) to test the scripts functionalityTHRESHOLD=80# Calculate the current percentage of used space on the /root partitionPERCENTAGE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')# Check if disk usage exceeds the assigned percentage thresholdif [ "$PERCENTAGE" -ge "$THRESHOLD" ]then# If disk free space is becoming problematic display a "Disk Space Alert"MESSAGE="WARNING: Disk usage on root partition is at ${PERCENTAGE}%!"# Calculate the estimated free space remaining on the /root partition (BTRFS file system specific)FREESPACE="$(btrfs filesystem usage / 2> /dev/null | grep -i 'Free (estimated):' | awk '{print $3}')"# WARNING=... embeds a "warning" icon in the first desktop notification# Error suppressed if the KDE Breeze icon set isn't present on the users systemWARNING=/usr/share/icons/breeze/emblems/24/emblem-warning.svg 2>/dev/null || true# IMPORTANT=... embeds an "important" icon in the second desktop notification# Error suppressed if the KDE Breeze icon set isn't present on the users systemIMPORTANT=/usr/share/icons/breeze/emblems/24/emblem-important.svg 2>/dev/null || true# Send a persistent desktop notification if drive usage percentage exceeds specified thresholdnotify-send -u critical -i "$WARNING" "Disk Space Alert" "$MESSAGE"# Pause 5 seconds before issuing a second disk space remaining notificationsleep 5# Send a fleeting desktop notification of estimated disk space remaining (BTRFS file system specific)notify-send -i "$IMPORTANT" "$FREESPACE" "space remaining on /root partition"echo "The check_disk timer was last executed on $(date +"%Y-%m-%d_%H:%M:%S") - drive capacity $PERCENTAGE % full" >> ~/.local/state/check_disk.log# If disk usage exceeds the script's assigned threshold write supplemental warnings to the ~/.local/state/check_disk.log fileecho -e "WARNING ... free space on the root partition has reached a dangerous level - $(date +"%Y-%m-%d_%H:%M:%S") \nNOTIFICATION ... steps must be taken to free up additional space or a system failure may occur" >> ~/.local/state/check_disk.log# In terminal output a "Disk Space Alert" when threshold is exceededecho "$MESSAGE"else# create a timestamped log entry - including drive usage statistics at that time the script was runecho "The check_disk timer was last executed on $(date +"%Y-%m-%d_%H:%M:%S") - drive capacity $PERCENTAGE % full" >> ~/.local/state/check_disk.log# In terminal display the percentage of used disk space and notify that current free space is sufficientecho -e "The root partition is currently filled to $PERCENTAGE% of the drive's capacity \nThere is an adequate amount of free space on your system partition"fi -
Make the script executable:
Terminal window chmod +x ~/.local/bin/check_disk.sh
Create the service and timer
Section titled “Create the service and timer”The service and timer are user units. They go in ~/.config/systemd/user/.
-
Create both files:
Terminal window mkdir -p ~/.config/systemd/usertouch ~/.config/systemd/user/check_disk.servicetouch ~/.config/systemd/user/check_disk.timer -
Paste the service below into
~/.config/systemd/user/check_disk.service.%hexpands to your home directory, so the path works without hard-coding it.# locations of all check_disk related files## this systemd service file# cat ~/.config/systemd/user/check_disk.service## other check_disk related files## cat ~/.config/systemd/user/check_disk.timer# cat ~/.local/bin/check_disk.sh# cat ~/.local/state/check_disk.log## systemctl commands for managing the check_disk.timer & check_disk.service## systemctl --user enable --now check_disk.timer# systemctl --user disable --now check_disk.timer# systemctl --user stop check_disk.timer# systemctl --user restart check_disk.timer# systemctl --user status check_disk.timer# systemctl --user daemon-reload (run command after altering check_disk.timer or check_disk.service)# systemctl --user status check_disk.service## do not enable or start the check_disk.service, the timer unit handles this operation[Unit]Description=Service to check free disk space hourly[Service]# %h expands to the path of the user's home directoryExecStart=%h/.local/bin/check_disk.sh -
Paste the timer below into
~/.config/systemd/user/check_disk.timer. It runs at the start of every hour, and once shortly after boot.# locations of all check_disk related files## this systemd timer file# cat ~/.config/systemd/user/check_disk.timer## other check_disk related files## cat ~/.config/systemd/user/check_disk.service# cat ~/.local/bin/check_disk.sh# cat ~/.local/state/check_disk.log## systemctl commands related to check_disk.timer & check_disk.service## systemctl --user enable --now check_disk.timer# systemctl --user disable --now check_disk.timer# systemctl --user daemon-reload (run command after altering check_disk.timer or check_disk.service)# systemctl --user restart check_disk.timer# systemctl --user stop check_disk.timer# systemctl --user --all list-timers# systemctl --user status check_disk.timer# systemctl --user status check_disk.service[Unit]Description=Check free disk space hourly[Timer]OnCalendar=*-*-* *:00:00AccuracySec=5mPersistent=trueUnit=check_disk.serviceOnBootSec=180[Install]WantedBy=timers.target -
Reload the user daemon, then enable and start the timer:
Terminal window systemctl --user daemon-reloadsystemctl --user enable --now check_disk.timer -
Check that the timer runs:
Terminal window systemctl --user status check_disk.timer
Test and manage
Section titled “Test and manage”Set THRESHOLD to 1 in the script for a test. Every run then shows a warning. Set it back to a real value afterwards.
-
Stop the hourly checks:
Terminal window systemctl --user stop check_disk.timer -
Start them again:
Terminal window systemctl --user restart check_disk.timer -
The timer also starts again after a reboot.
Each run appends a line to ~/.local/state/check_disk.log. The log is deleted when it grows past 1 MB.
Troubleshooting
Section titled “Troubleshooting”If the service fails with Neither a valid executable name nor an absolute path, use the %h form from step 2 of the service. This error was reported with ~/.local/bin/check_disk.sh in ExecStart=.
If the notifications do not appear, check that libnotify is installed and that a notification daemon runs in your session. A forum reply suggested setting DBUS_SESSION_BUS_ADDRESS in the script. Another reply noted that user units normally inherit the session bus, so the variable is not needed for a user timer.
Auto installer
Section titled “Auto installer”An automatic installer exists that creates these files and can update them. It is a remote script, so read it before you run it. The installer replaces any changes you made to the files.
Source: How to write a script, service, and timer to help prevent a drive being filled to capacity