DEV Community

Haripriya Veluchamy
Haripriya Veluchamy

Posted on

Creating a Safer rm Command: Your Linux Safety Net

We've all been there: that moment of sheer panic when you realize you just deleted an important file with the rm command. Unlike other operating systems with their forgiving Recycle Bins, Linux's rm command is brutally final. But what if we could change that?

In this tutorial, I'll show you how to create your own trash-enabled version of the rm command that moves files to a trash directory instead of permanently deleting them. It's perfect for beginners who are still getting comfortable with the command line, or even for experienced users who want an extra safety net.

The Problem with rm

The standard rm command in Linux is designed to be efficient, not forgiving. When you run rm file.txt, that file is gone forever. There's no confirmation dialog, no second chances. While this is great for system performance, it can be a nightmare for users who make mistakes.

Many GUI file managers in Linux already implement a trash system, but terminal users are left without this safety net. That's where our custom rm command comes in.

What We're Building

We'll create a custom shell script that:

  1. Intercepts the rm command
  2. Moves the specified files to a trash directory instead of deleting them
  3. Maintains the same command-line interface as the original rm command
  4. Adds timestamps to filenames to prevent conflicts in the trash

Prerequisites

  • A Linux system (or WSL on Windows)
  • Basic knowledge of the terminal
  • Text editor (nano, vim, etc.)

Step 1: Setting Up the Trash Directory

First, let's create a directory to store our "deleted" files:

mkdir -p /tmp/trash
chmod 777 /tmp/trash
Enter fullscreen mode Exit fullscreen mode

I'm using /tmp/trash for this tutorial, but be aware that files in /tmp might be cleared during system reboots. For a more permanent solution, you might want to use ~/.trash instead.

Step 2: Creating Our Custom rm Script

Next, we'll create a personal bin directory and our custom script:

mkdir -p ~/bin
touch ~/bin/rm
chmod +x ~/bin/rm
Enter fullscreen mode Exit fullscreen mode

Now, let's edit the script:

nano ~/bin/rm
Enter fullscreen mode Exit fullscreen mode

And paste in the following code:

#!/bin/bash

# Custom rm command that moves files to trash instead of deleting them

# Get the current date and time for uniqueness
DATE=$(date +%Y%m%d_%H%M%S)

# Process command line arguments
force=false
recursive=false
verbose=false
files=()

# Parse arguments
for arg in "$@"; do
  case $arg in
    -f|--force)
      force=true
      ;;
    -r|-R|--recursive)
      recursive=true
      ;;
    -v|--verbose)
      verbose=true
      ;;
    -*)
      # For other options, pass them to the real rm command if needed
      ;;
    *)
      files+=("$arg")
      ;;
  esac
done

# Check if no files were specified
if [ ${#files[@]} -eq 0 ]; then
  echo "rm: missing operand"
  echo "Try 'rm --help' for more information."
  exit 1
fi

# Process each file
for file in "${files[@]}"; do
  # Check if file exists
  if [ ! -e "$file" ] && [ ! -L "$file" ]; then
    if [ "$force" = true ]; then
      # If force option is used, silently ignore non-existent files
      continue
    else
      echo "rm: cannot remove '$file': No such file or directory"
      exit 1
    fi
  fi

  # Get the filename without path
  filename=$(basename "$file")

  # Create a unique name in case of duplicates in trash
  trash_name="${filename}_${DATE}"

  # Move the file to trash
  if mv "$file" "/tmp/trash/$trash_name"; then
    if [ "$verbose" = true ]; then
      echo "Moved '$file' to trash as '$trash_name'"
    fi
  else
    echo "Failed to move '$file' to trash"
    exit 1
  fi
done

exit 0
Enter fullscreen mode Exit fullscreen mode

Step 3: Understanding the Script

Let's break down what this script does:

  1. #!/bin/bash - This is called a "shebang" and tells the system to use the Bash shell to run this script.

  2. DATE=$(date +%Y%m%d_%H%M%S) - Creates a timestamp variable that we'll use to make filenames unique in the trash.

  3. We set up variables to track command options (-f for force, -r for recursive, -v for verbose).

  4. The for arg in "$@" loop processes each command-line argument:

    • If it's -f, we set force=true
    • If it's -r or -R, we set recursive=true
    • If it's -v, we set verbose=true
    • If it's any other option (starts with -), we ignore it for now
    • If it's not an option, we assume it's a filename and add it to our files array
  5. We check if the user provided any filenames at all.

  6. The main loop processes each filename:

    • Check if the file exists (unless -f was used)
    • Extract just the filename (without path)
    • Create a unique trash name with the timestamp
    • Move the file to the trash directory
    • If -v was used, show what happened

Step 4: Adding Our Script to the PATH

For our custom script to take precedence over the system's built-in rm command, we need to add our ~/bin directory to the beginning of the PATH environment variable:

echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
Enter fullscreen mode Exit fullscreen mode

This tells your shell to look in your personal bin directory before checking the system directories when you run a command.

Step 5: Testing Our Command

Let's create a test file and try out our new safety net:

# Create a test file
echo "important data" > important.txt

# "Delete" it with our custom rm
rm important.txt

# Check that it's in the trash
ls -la /tmp/trash
Enter fullscreen mode Exit fullscreen mode

You should see your file in the trash directory with a timestamp appended to its name!

Script Breakdown for Beginners

If you're new to shell scripting, here's what's happening in plain English:

  1. We create a script that pretends to be the rm command.
  2. When you run rm file.txt, our script runs instead of the real one.
  3. Our script doesn't delete the file; it moves it to our trash folder.
  4. It adds a timestamp to the filename to prevent conflicts.
  5. It tries to behave like the real rm command so you won't notice a difference.

Taking It Further: Trash Management

Our basic implementation works, but you might want to add some additional features:

Trash Cleanup Script

Create a script to automatically delete files from the trash after a certain period:

#!/bin/bash
# trash-empty script to remove files older than 7 days
find /tmp/trash -type f -mtime +7 -exec /bin/rm -f {} \;
Enter fullscreen mode Exit fullscreen mode

File Recovery Script

Create a script to restore files from the trash:

#!/bin/bash
# trash-restore script
if [ $# -eq 0 ]; then
  echo "Usage: trash-restore FILENAME"
  exit 1
fi

ls -l /tmp/trash | grep $1
echo "Enter the exact filename to restore: "
read filename

if [ -f "/tmp/trash/$filename" ]; then
  # Extract original filename before the timestamp
  original=$(echo $filename | sed 's/_[0-9]\{8\}_[0-9]\{6\}$//')
  mv "/tmp/trash/$filename" "./$original"
  echo "Restored $filename as $original"
else
  echo "File not found in trash"
fi
Enter fullscreen mode Exit fullscreen mode

Limitations and Considerations

While our custom rm command provides a nice safety net, there are some limitations to be aware of:

  1. Temporary Storage: If you're using /tmp/trash, files might be cleared during system reboots.

  2. Root Access: If you run commands with sudo, it might bypass your custom script and use the system's rm command.

  3. Disk Space: Unlike true deletion, our approach does consume disk space until you empty the trash.

  4. Complex Operations: We've implemented basic functionality, but complex operations like removing directories recursively might need additional logic.

Conclusion

Creating a trash-enabled rm command is a perfect beginner project that teaches valuable shell scripting concepts while adding a genuine safety feature to your Linux experience. It demonstrates how we can modify and extend core system functionality without changing the original commands.

The beauty of Linux is its flexibility—if you don't like how something works, you can change it to better suit your needs. This project is a perfect example of that philosophy in action.

Have you created your own custom commands to improve your Linux experience? Share them in the comments below!


GitHub Repository

I've made this project available on github. Feel free to fork it, improve it, and share your enhancements!

Heroku

Deploy with ease. Manage efficiently. Scale faster.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (0)