Forums
New posts
Articles
Product Reviews
Policies
FAQ
Log in
Register
What's new
Search
Search
Search titles only
By:
New posts
Menu
Log in
Register
Install the app
Install
Forums
macOS & iOS Developer Playground
macOS - Development and Darwin
Bash script instead of rm to prompt with number of files about to delete (a safer rm)
JavaScript is disabled. For a better experience, please enable JavaScript in your browser before proceeding.
You are using an out of date browser. It may not display this or other websites correctly.
You should upgrade or use an
alternative browser
.
Reply to thread
Message
<blockquote data-quote="OS/4" data-source="post: 1792849" data-attributes="member: 358964"><p><strong>Background</strong></p><p>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 "<u>rm</u> 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.</p><p></p><p>I don't want to start using rm -i, because I hate that it prompts for <em>every single file</em> - annoying when you're deleting many!</p><p>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 ;-)</p><p></p><p>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:</p><p></p><p><strong>rmi.sh</strong></p><p>[CODE]#!/bin/bash</p><p># Writes out how many files and then prompts for deletion</p><p>if [ "$#" -eq 0 ] ; then</p><p> echo "usage: rmi [-R] file ..."</p><p> exit 1</p><p>fi</p><p></p><p>RECURSIVE=""</p><p>for PARAM in "$@" ; do</p><p> if [ "$PARAM" = "-R" ] ; then</p><p> RECURSIVE="-R "</p><p> fi</p><p>done</p><p></p><p>if [ -z "$RECURSIVE" ] ; then</p><p> NUMBER=0</p><p> for PARAM in "$@" ; do</p><p> if [ -f "$PARAM" ] ; then</p><p> ((NUMBER+=$(ls -1Ap "$PARAM" | grep -c '[^:]$')))</p><p> fi</p><p> done</p><p>else</p><p> NUMBER=$(ls -1Ap $RECURSIVE "$@" | grep -c '[^:]$')</p><p>fi</p><p></p><p>if [ $NUMBER = 0 ] ; then</p><p> echo "rmi: $@: No such file or directory"</p><p>else</p><p> read -n 1 -p "Deleting $NUMBER file(s), Are you sure (Y/N)? " yn</p><p> echo</p><p> if [ "$yn" != "${yn#[Yy]}" ] ; then</p><p> [COLOR="#FF0000"]# [/COLOR]rm "$@"</p><p> fi</p><p>fi[/CODE]</p><p></p><p><span style="color: #008000"><strong>I would greatly appreciate if someone with more UNIX/shell skills could point ot any flaws in this.</strong></span></p><p></p><p>1. What I'm not happy with, is that I need the if [ -z "$RECURSIVE" ] ... it feels like a hack.</p><p>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 <em>and directories</em> in the current directory and then the ls command also picks up the files in the first level of <em>sub</em>-directories.</p><p></p><p>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).</p><p></p><p>3. I don't mind that it's wrong with "." or ".." as args, rm doesn't work with those anyway.</p><p></p><p>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.</p><p></p><p>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).</p><p></p><p><span style="color: #FF0000">I have commented out the only call to actual "rm" so I can test it safely.</span></p><p></p><p>Many thanks to anyone who bothers to look at my script ;-)</p></blockquote><p></p>
[QUOTE="OS/4, post: 1792849, member: 358964"] [B]Background[/B] 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 "[U]rm[/U] 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 [I]every single file[/I] - 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: [B]rmi.sh[/B] [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[/CODE] [COLOR="#008000"][B]I would greatly appreciate if someone with more UNIX/shell skills could point ot any flaws in this.[/B][/COLOR] 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 [I]and directories[/I] in the current directory and then the ls command also picks up the files in the first level of [I]sub[/I]-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). [COLOR="#FF0000"]I have commented out the only call to actual "rm" so I can test it safely.[/COLOR] Many thanks to anyone who bothers to look at my script ;-) [/QUOTE]
Verification
Post reply
Forums
macOS & iOS Developer Playground
macOS - Development and Darwin
Bash script instead of rm to prompt with number of files about to delete (a safer rm)
Top