[2025-jun-17] The SlackDocs mailing lists at https://lists.alienbase.nl/mailman/listinfo have been retired. No one has been using these lists for years and it's time to say goodbye. The list archives remain available at https://scalzi.slackware.nl/mailman/listinfo/slackdocs

[2025-jun-17] The SlackDocs Wiki has moved to a new server, in order to make it more performant.

Welcome to the Slackware Documentation Project

Custom /tmp Cleanup at Boot

Slackware does not aggressively clean /tmp on boot by default. Over time, leftover files from interrupted SlackBuilds, build artifacts, runtime sockets, lock files, and abandoned temporary data accumulate in /tmp, sometimes growing to several gigabytes. This howto explains how to set up automated cleanup using the TMP_REMOVE_SCRIPT hook in Slackware -current.

Background

The /etc/rc.d/rc.S script in Slackware -current sources /etc/default/tmp-cleanup early in the boot process. This file defines two cleanup mechanisms:

  • TMP_REMOVE_LIST — a list of glob patterns that are passed to rm -rf from within /tmp
  • TMP_REMOVE_SCRIPT — a path to a custom executable script that runs after the default list is processed

The TMP_REMOVE_LIST mechanism handles common runtime garbage (X11 lock files, KDE/Plasma session leftovers, dbus sockets, mc and pulseaudio leftovers). It is intentionally conservative — it does not remove SlackBuild artifacts, build directories, or downloaded packages, because those may represent unfinished user work.

The TMP_REMOVE_SCRIPT hook gives administrators a place to add system-specific cleanup logic without modifying rc.S directly. This is the recommended way to add aggressive /tmp cleanup.

Historical context

The TMP_REMOVE_SCRIPT hook is only available in Slackware -current. Slackware 15.0 and earlier versions do not include it.

Before this feature existed, users typically used one of these approaches:

  • rc.local_shutdown — a script run at shutdown that cleared /tmp. Common pattern: find /tmp -mindepth 1 -maxdepth 1 -mtime +7 -exec rm -rf {} +
  • tmpfs on /tmp — adding a tmpfs entry to /etc/fstab, so /tmp lives in RAM and is recreated empty on every boot
  • cron jobs — periodic find /tmp -mtime +N -delete scheduled via cron
  • Direct editing of rc.0 or rc.6 — not recommended, since these are overwritten by package updates

These approaches still work on Slackware -current, but TMP_REMOVE_SCRIPT is cleaner because it integrates with the existing rc.S boot flow and is not affected by package upgrades to aaa_base.

The /etc/default/tmp-cleanup file

On Slackware -current, /etc/default/tmp-cleanup looks like this:

# List files/directories to remove when the machine is booted.
TMP_REMOVE_LIST="/etc/nologin /etc/dhcpc/*.pid ... tmp.??????????"

# You may also run a custom cleanup script by pointing to it here:
#TMP_REMOVE_SCRIPT=/usr/local/sbin/custom-cleanup-script.sh

The TMP_REMOVE_SCRIPT line is commented out by default. To activate it, uncomment the line and point it to your script.

Creating the cleanup script

A safe location for the cleanup script is /usr/local/sbin/, which is owned by root and not affected by package upgrades.

Minimal example

The simplest possible cleanup script removes everything in /tmp:

/usr/local/sbin/custom-cleanup-script.sh
#!/bin/bash
# Aggressive /tmp cleanup at boot
 
cd /tmp || exit 1
find . -mindepth 1 -maxdepth 1 -exec rm -rf {} +

This is functionally equivalent to making /tmp a tmpfs. It removes all files in /tmp on every boot, including .X11-unix, .ICE-unix, and other directories that rc.S will recreate later. Use this only if you are comfortable with that behavior.

Selective cleanup with logging

A more conservative approach removes only specific patterns and logs what was cleaned:

/usr/local/sbin/custom-cleanup-script.sh
#!/bin/bash
#
# /usr/local/sbin/custom-cleanup-script.sh
# Selective /tmp cleanup at boot, with safety checks and logging.
 
set -u
 
TARGET=/tmp
LOG=/var/log/tmp-cleanup.log
 
# Reset log on every boot
echo "=== $(date) ===" > "$LOG"
 
# Safety check 1: TARGET must be exactly /tmp
if [ "$TARGET" != "/tmp" ]; then
    echo "FATAL: TARGET is '$TARGET', not '/tmp'. Aborting." >> "$LOG"
    exit 1
fi
 
# Safety check 2: TARGET must be a real directory, not a symlink
if [ ! -d "$TARGET" ] || [ -L "$TARGET" ]; then
    echo "FATAL: $TARGET is not a real directory. Aborting." >> "$LOG"
    exit 1
fi
 
# Safety check 3: cd must succeed
cd "$TARGET" || {
    echo "FATAL: cannot cd to $TARGET. Aborting." >> "$LOG"
    exit 1
}
 
# Safety check 4: pwd must be exactly /tmp after cd
if [ "$(pwd -P)" != "/tmp" ]; then
    echo "FATAL: pwd is '$(pwd -P)', not '/tmp'. Aborting." >> "$LOG"
    exit 1
fi
 
echo "Safety checks passed. Cleaning $TARGET" >> "$LOG"
 
# Remove SlackBuild work directory entirely
rm -rf SBo >> "$LOG" 2>&1
 
# Remove generated Slackware packages
find . -maxdepth 1 -type f \( -name "*.tgz" -o -name "*.txz" \) -print -delete >> "$LOG" 2>&1
 
# Remove SlackBuild DESTDIR directories
find . -maxdepth 1 -type d -name "package-*" -print -exec rm -rf {} + >> "$LOG" 2>&1
 
# Remove extracted source directories matching name-version pattern
find . -maxdepth 1 -type d -regex './[a-zA-Z][a-zA-Z0-9_-]*-[0-9][0-9.]*.*' -print -exec rm -rf {} + >> "$LOG" 2>&1
 
# Remove build logs
find . -maxdepth 1 -type f -name "*.log" -delete >> "$LOG" 2>&1
 
# Remove orphaned wget lock files
find . -maxdepth 1 -name ".wget-*_lck_*" -delete >> "$LOG" 2>&1
 
# Remove Go build caches
find . -maxdepth 1 -name "go-build*" -exec rm -rf {} + >> "$LOG" 2>&1
 
echo "" >> "$LOG"
du -sh /tmp >> "$LOG" 2>&1

The four safety checks at the top of the script are essential. Because the script runs as root at boot, any mistake can be catastrophic. The checks ensure:

  • The target is hardcoded and not influenced by environment variables
  • The target exists and is a real directory (not a symlink that could redirect the script elsewhere)
  • The cd actually succeeded before any rm or find is executed
  • The current working directory after cd is physically /tmp

If any check fails, the script logs the failure and exits without removing anything. This converts what could be a system-destroying bug into a harmless boot-time warning.

Activating the script

After creating the script:

# chown root:root /usr/local/sbin/custom-cleanup-script.sh
# chmod 755 /usr/local/sbin/custom-cleanup-script.sh

Then edit /etc/default/tmp-cleanup and uncomment the TMP_REMOVE_SCRIPT line:

TMP_REMOVE_SCRIPT=/usr/local/sbin/custom-cleanup-script.sh

Test the script manually before relying on it at boot:

# /usr/local/sbin/custom-cleanup-script.sh
# echo "Exit code: $?"
# cat /var/log/tmp-cleanup.log

If the exit code is 0 and the log shows expected behavior, the script will run cleanly on the next boot.

When to use this approach versus tmpfs

For systems with sufficient RAM, mounting /tmp as tmpfs is simpler and provides automatic cleanup without any script:

tmpfs  /tmp  tmpfs  defaults,size=8G,mode=1777,nodev,nosuid  0 0

The tmpfs approach matches the FHS recommendation that /tmp contents should not persist between boots.

TMP_REMOVE_SCRIPT is preferable when:

  • /tmp must persist across reboots for some reason (interrupted long-running builds)
  • RAM is limited and dedicating space to tmpfs is undesirable
  • Custom cleanup logic is needed (selective patterns, logging, retention rules)
  • The system rarely reboots, so persistence between sessions matters more than automatic cleanup

See also

Sources

* Originally written by r1w1s1

QR Code
QR Code howtos:general_admin:custom_tmp_cleanup_at_boot (generated for current page)