Bash script instead of rm to prompt with number of files about to delete (a safer rm)

Joined
Jul 27, 2015
Messages
10
Reaction score
0
Points
1
Background
I always review my rm command line carefully before executing, so I thought I'd be fine. The other day while using the command history, I recalled and executed a previous command, thinking it's "ls some files", but didn't notice it's "rm some files". I executed that in a different dir before, but the same files happened to be in the current dir and got deleted - oops.

I don't want to start using rm -i, because I hate that it prompts for every single file - annoying when you're deleting many!
What I really want is a single "are you sure" prompt, so this can't happen again. I'd also like it to tell me how many files I'm about to delete, because that would act as a sanity check (especially when using -R and accidentally being in a directory higher up ;-)

I came across the idea to count the files using grep on the output of "ls". It looked promisingly simple, but then I tested it with wildcards and files with spaces and it got a bit more complicated than I would have liked:

rmi.sh
Code:
#!/bin/bash
# Writes out how many files and then prompts for deletion
if [ "$#" -eq 0 ] ; then
    echo "usage: rmi [-R] file ..."
    exit 1
fi

RECURSIVE=""
for PARAM in "$@" ; do
    if [ "$PARAM" = "-R" ] ; then
        RECURSIVE="-R "
    fi
done

if [ -z "$RECURSIVE" ] ; then
    NUMBER=0
    for PARAM in "$@" ; do
        if [ -f "$PARAM" ] ; then
            ((NUMBER+=$(ls -1Ap "$PARAM" | grep -c '[^:]$')))
        fi
    done
else
    NUMBER=$(ls -1Ap $RECURSIVE "$@" | grep -c '[^:]$')
fi

if [ $NUMBER = 0 ] ; then
    echo "rmi: $@: No such file or directory"
else
    read -n 1 -p "Deleting $NUMBER file(s), Are you sure (Y/N)? " yn
    echo
    if [ "$yn" != "${yn#[Yy]}" ] ; then
        [COLOR="#FF0000"]# [/COLOR]rm "$@"
    fi
fi

I would greatly appreciate if someone with more UNIX/shell skills could point ot any flaws in this.

1. What I'm not happy with, is that I need the if [ -z "$RECURSIVE" ] ... it feels like a hack.
I would like a simple ls -1Ap "$@", but if I call the script with a single * wildcard, the shell expands it and passes all files and directories in the current directory and then the ls command also picks up the files in the first level of sub-directories.

2. I don't mind if it only works in bash. I don't mind if the only option that works is -R (which happens to work the same for rm and ls).

3. I don't mind that it's wrong with "." or ".." as args, rm doesn't work with those anyway.

4. I've added "-p" to the "ls" because I thought I might filter out directories (from the number of file(s) reported) based on ending with a slash later, but I don't really mind.

5. I would train myself to use an alias called "rmi" (short for "rm -i" ;-) rather than set up an "rm" alias that lures me into safety and might be disastrous if the alias isn't there (e.g. on a different computer).

I have commented out the only call to actual "rm" so I can test it safely.

Many thanks to anyone who bothers to look at my script ;-)
 
Last edited:
OP
O
Joined
Jul 27, 2015
Messages
10
Reaction score
0
Points
1
I found out about the -d option on ls, which avoid listing directory contents if a dir is specified (or expanded from *). That makes the script simpler:

Code:
#!/bin/bash
# Writes out how many files and then prompts for deletion
if [ "$#" -eq 0 ] ; then
    echo "usage: rmi [-f | -i] [-PRrvW] file ..."
    exit 1
fi

FLAGS="d" # don't go into specified/expanded directories unless recursive flag (below)
for PARAM in "$@" ; do
    if [ "$PARAM" = "-r" ] || [ "$PARAM" = "-R" ] ; then
        FLAGS="R"
    fi
done

NUMBER=$(ls -1APp$FLAGS "$@" 2>/dev/null | grep -c '[^/:]$') # don't count directories or directory headings
if [ $NUMBER = 0 ] ; then
    echo "rmi: $@: No such file or directory"
else
    read -n 1 -p "Deleting $NUMBER file(s), Are you sure (Y/N)? " yn
    echo
    if [ "$yn" != "${yn#[Yy]}" ] ; then
        echo rm "$@"
    fi
fi

So now the only questions I would have for someone experienced with UNIX is whether there are any big dangers or flaws in this script. Thanks!
 

Shop Amazon


Shop for your Apple, Mac, iPhone and other computer products on Amazon.
We are a participant in the Amazon Services LLC Associates Program, an affiliate program designed to provide a means for us to earn fees by linking to Amazon and affiliated sites.
Top