Skip to main content

Command Palette

Search for a command to run...

Bash-Based Recycle Bin: Auto-Clean Old Files After 30 Days

Published
2 min readView as Markdown

Instead of permanently deleting files with rm, I’ve started using a lightweight “recycle bin” system in Bash. Here’s how it works:

  • Files are moved to ~/30_day_recycle_bin/ using a simple shell function

  • A script called hoover_rubbish.sh runs occasionally and deletes anything older than 30 days

  • A log file keeps track of what was deleted and when

It’s minimalist, scriptable, and keeps my home directory clean.

The bin Function (Soft Delete)

Add this to your ~/.bashrc:

bin() {
  if [ $# -eq 0 ]; then
    echo "Usage: bin <file1> [file2 ...]"
    return 1
  fi
  mv "$@" ~/30_day_recycle_bin/
}

Now instead of doing:

rm important_file.txt  # 😬

I just run:

bin important_file.txt

This gives me a 30-day grace period to recover anything I delete “just in case.”

The Cleanup Script: hoover_rubbish.sh

This script goes through the recycle bin and deletes files that haven’t been accessed or modified in the last 30 days.

#!/bin/bash

RECYCLE_DIR="/home/roy/30_day_recycle_bin"
LOG_FILE="$RECYCLE_DIR/hoover_rubbish.log"
CURRENT_DATE=$(date "+%Y-%m-%d %H:%M")

# Ensure directory exists
if [[ ! -d "$RECYCLE_DIR" ]]; then
    echo "Error: Directory $RECYCLE_DIR does not exist."
    exit 1
fi

# Log header
echo "" >> "$LOG_FILE"
echo "==============================" >> "$LOG_FILE"
echo "$CURRENT_DATE: Script executed." >> "$LOG_FILE"

# List all files
ALL_FILES=$(find "$RECYCLE_DIR" -type f)
if [[ -z "$ALL_FILES" ]]; then
    echo "$CURRENT_DATE: No files found." >> "$LOG_FILE"
else
    echo "$CURRENT_DATE: Found files:" >> "$LOG_FILE"
    printf "%-60s %-25s %-25s\n" "File" "atime" "mtime" >> "$LOG_FILE"
    printf "%-60s %-25s %-25s\n" "----" "-----" "-----" >> "$LOG_FILE"

    while IFS= read -r FILE; do
        ATIME=$(stat --format='%x' "$FILE" | cut -d'.' -f1)
        MTIME=$(stat --format='%y' "$FILE" | cut -d'.' -f1)
        printf "%-60s %-25s %-25s\n" "$FILE" "$ATIME" "$MTIME" >> "$LOG_FILE"
    done <<< "$ALL_FILES"

    # Find stale files
    FILES_TO_DELETE=$(find "$RECYCLE_DIR" -type f -atime +30 -mtime +30)
    if [[ -z "$FILES_TO_DELETE" ]]; then
        echo "$CURRENT_DATE: No files to delete." >> "$LOG_FILE"
    else
        echo "$CURRENT_DATE: Deleting files:" >> "$LOG_FILE"
        while IFS= read -r FILE; do
            echo "$FILE" >> "$LOG_FILE"
            rm -f "$FILE"
        done <<< "$FILES_TO_DELETE"
        echo "$CURRENT_DATE: Deleted old files." >> "$LOG_FILE"
    fi
fi

Why Use Both atime and mtime?

Some files might be read (atime) but not changed (mtime), or vice versa. By checking both, I make sure the file has been truly untouched for 30 days (no reads, no writes).

Cron It

To automate cleanup, you could add this to your crontab:

0 3 * * * /home/roy/scripts/hoover_rubbish.sh

That runs it every day at 3 AM.

Final Thoughts

This is a zero-stress way to soft-delete files and let them expire naturally after 30 days. No more worrying about accidentally deleted the wrong thing.

More from this blog

RH Scripts

16 posts