This script replaces the standard rm command with a safer alternative that moves files to the macOS Trash instead of deleting them permanently. The implementation uses shell functions and aliases to intercept rm calls and redirect them to a custom safe_rm function.
The primary purpose is to prevent accidental data loss. The standard rm command deletes files immediately and irreversibly. This implementation moves files to the system Trash (~/.Trash), where they can be recovered if needed.
- The
safe_rmfunction is defined in~/.bash_aliases. - The
alias rm='safe_rm'command redirects allrminvocations to thesafe_rmfunction. - When
rmis called, the function:- Verifies the Trash directory exists and creates it if missing
- Processes each argument passed to
rm - Checks if each file or directory exists
- Moves files to
~/.Trash/Filesand directories to~/.Trash - Reports success or failure for each operation
Create or edit ~/.bash_aliases with the following content:
# Safe rm alias: moves files to Trash instead of deleting permanently
# macOS-only implementation with enhanced error handling and safeguards
# Function to move file/directory to Trash
safe_rm() {
local file
local trash_dir
local confirm
# macOS: use the standard Trash directory
trash_dir="$HOME/.Trash"
# Create Trash directory if it doesn't exist
if [[ ! -d "$trash_dir" ]]; then
mkdir -p "$trash_dir"
if [[ $? -ne 0 ]]; then
echo "Error: Failed to create Trash directory at $trash_dir"
return 1
fi
fi
# Check if any arguments were provided
if [[ $# -eq 0 ]]; then
echo "Usage: safe_rm <file|directory>..."
return 1
fi
# Process each argument
for file in "$@"; do
# Check if file exists
if [[ ! -e "$file" ]]; then
echo "Error: File not found: $file"
continue
fi
# Check if file is a directory
if [[ -d "$file" ]]; then
# For directories, use mv to move entire directory
if [[ -d "$trash_dir/Files" ]]; then
mv "$file" "$trash_dir/Files/"
else
mv "$file" "$trash_dir/"
fi
else
# For files, move to Files directory
if [[ -d "$trash_dir/Files" ]]; then
mv "$file" "$trash_dir/Files/"
else
mv "$file" "$trash_dir/"
fi
fi
# Check if mv was successful
if [[ $? -ne 0 ]]; then
echo "Error: Failed to move '$file' to Trash"
continue
fi
# Print confirmation
echo "Moved to Trash: $file"
done
}
# Create alias for rm to use safe_rm function
alias rm='safe_rm'
# Optional: Add a command to empty the Trash
empty_trash() {
local trash_dir
trash_dir="$HOME/.Trash"
if [[ -d "$trash_dir/Files" ]]; then
rm -rf "$trash_dir/Files"
echo "Trash emptied (Files directory)"
elif [[ -d "$trash_dir" ]]; then
rm -rf "$trash_dir"
echo "Trash emptied"
else
echo "Trash directory not found"
fi
}
# Create alias for emptying Trash
alias empty-trash='empty_trash'
# Optional: Add a command to list contents of Trash
list_trash() {
local trash_dir
trash_dir="$HOME/.Trash"
if [[ -d "$trash_dir/Files" ]]; then
ls -la "$trash_dir/Files"
elif [[ -d "$trash_dir" ]]; then
ls -la "$trash_dir"
else
echo "Trash directory not found"
fi
}
# Create alias for listing Trash contents
alias list-trash='list_trash'Create or edit ~/.bash_noninteractive with the following content:
# Configure non-interactive Bash environment to ensure aliases are available
# Enable alias expansion in non-interactive shells
shopt -s expand_aliases
# Source user-defined aliases
source ~/.bash_aliasesAdd the following line to your ~/.bash_profile or ~/.bashrc:
export BASH_ENV=~/.bash_noninteractiveReload your shell configuration:
source ~/.bash_aliasesAfter sourcing the configuration:
rm file.txt # Moves file.txt to Trash
rm -rf directory/ # Recursively moves directory/ to Trash
rm *.log # Moves all .log files to Trash
rm -rf ./foo/*.doc # Moves all .doc files in ./foo to Trash- Error checking: The function validates file existence and directory creation before attempting moves.
- Success verification: Each
mvoperation is checked for success. - Clear feedback: Each operation reports whether it succeeded or failed.
- Usage guidance: The function provides help text when no arguments are given.
The configuration includes three additional aliases:
empty-trash: Removes all files from the Trashlist-trash: Lists the contents of the Trashsafe_rm: The underlying function (not intended for direct use)
- This implementation is macOS-only. It uses the standard macOS Trash location (
~/.Trash). - The function does not support interactive confirmation prompts by default. The commented-out code provides this functionality if needed.
- The implementation assumes the user has write permissions to
~/.Trash. - The function does not handle symbolic links specially; they are moved as-is.
- The function does not preserve file metadata (modification times, permissions) during the move.
- The script runs with the user's privileges. It cannot access files outside the user's home directory.
- The script does not log actions. Recovery requires manual inspection of the Trash.
- The script does not provide versioning or history tracking. Files in the Trash are not recoverable after emptying.
To use the original rm command when needed:
command rm file.txt # Uses the original rm command
/bin/rm file.txt # Direct path to rm binaryThe implementation is a direct, functional solution to a common problem: preventing accidental file deletion. It does not claim to be a complete file recovery system, but it provides a simple, reliable way to avoid irreversible data loss in everyday command-line use.