Results 1 to 2 of 2
  1. #1
    Post Bash script instead of rm to prompt with number of files about to delete (a safer rm)
    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
            # 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 by OS/4; 05-24-2018 at 05:54 PM.

  2. #2
    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!

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. rSync commandline bash script
    By scar1 in forum macOS - Operating System
    Replies: 2
    Last Post: 03-19-2015, 09:49 PM
  2. Safer way to download movie files?
    By siemens10520 in forum Movies and Video
    Replies: 5
    Last Post: 02-28-2010, 11:41 AM
  3. Help with the bash...alias/script...?
    By Antares in forum macOS - Development and Darwin
    Replies: 2
    Last Post: 10-26-2009, 12:32 PM
  4. How Do I Get Finder to Execute a Bash Script?
    By mac57 in forum macOS - Development and Darwin
    Replies: 7
    Last Post: 06-08-2006, 03:01 PM
  5. Bash Script
    By ftjogoh in forum Apple Notebooks
    Replies: 1
    Last Post: 11-04-2004, 02:14 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •