Path: utzoo!attcan!uunet!vsedev!logan From: logan@vsedev.VSE.COM (James Logan III) Newsgroups: comp.unix.questions Subject: Re: Creating a nondestructive 'rm' Message-ID: <1226@vsedev.VSE.COM> Date: 6 Nov 88 05:43:31 GMT References: <4460006@hpindda.HP.COM> Reply-To: logan@vsedev.VSE.COM (James Logan III) Organization: VSE Software Development Lab Lines: 194 In article <4460006@hpindda.HP.COM> burdick@hpindda.HP.COM (Matt Burdick) writes: >Does anyone have a nice alias or shell script so that when I 'rm' a file it >will actually move it to, for instance, a tmp subdirectory in my home >directory? Yes, I do. I just wrote it last week and have not thouroughly tested it, but as far as I can tell, it works fine. My version COPIES each file, rather than moving it so that it can be used across partitions. Unfortunately, you must have read access to the file in order to remove it with this script. If you don't have read access, just use /bin/rm or move the file manually. Basically, rm() copies each file you want removed to a directory called "trash" in your $HOME directory. If you want this trash directory to be called something else, just set the environment variable "TRASH" to the full pathname of the directory. When invoked with the -r option, rm() will copy every file under the specified directory and remove the directory. Each file is copied to $TRASH, but the original hierarchy is not retained so be careful when you remove two files with the same name in different sub-directories! The -i flag works pretty much like the real rm. Once a month I usually use the "discard" function to remove all of these files with /bin/rm for real. It will prompt you for permission to delete each file unless you use the -f option. One problem with discard() is that I forgot to make it remove invisible files that have filenames beginning with ".". (Sorry that I haven't written a man page for these yet -- I just haven't gotten around to it... If there is any interest I will post the man pages sometime next week or so...) I define these functions in a file called ".kshrc" in my home directory and set the ksh's ENV variable so that these functions will be read by each sub-shell. I wrote these functions to be portable between the Bourne shell and the Korn shell. Just send me email if you want details on using these functions in Bourne shell-script form... I used only variable names that start with an underscore so that they would not interfere with any other scripts. Also, I unset the variables I use in rm() since the option flags stay permanently set otherwise. If you find any bugs or can think of any enhancements, just send me email. -Jim ------------------------------------------------------------------------------- hastrash() { # Written by James Logan (vsedev!logan) 11/88 # Check existence of $TRASH if test -z "$TRASH"; then TRASH=$HOME/trash; fi; if test ! -d "$TRASH"; then echo >&2 "$0: Making trash directory $TRASH...\c"; if mkdir "$TRASH"; then echo >&2 "done."; else echo >&2 "\n$0: Cannot make directory $TRASH"; return 1; fi; fi; if test ! -w "$TRASH"; then echo >&2 "$0: Cannot write in $TRASH."; return 1; fi; return 0; } rm() { # Written by James Logan (vsedev!logan) 11/88 # Take out this next line when you are sure that /bin/rm is # not being called by mistake. echo >&2 "(rm() function)"; unset _ARG _RECURSIVE _NOERROR _INTERACTIVE _COMMAND _FILE _RESP; hastrash || return 1; if test $# = 0; then echo >&2 "usage: $0 [-rfi] file ..."; return 1; fi; set -- `getopt "rfi" $*`; for _ARG in $*; do case "$_ARG" in -r) _RECURSIVE=1; ;; -f) _NOERROR=1; ;; -i) _INTERACTIVE=1; ;; --) shift; break; ;; esac; shift; done; if test "$_RECURSIVE"; then _COMMAND="find $* -type f -print"; else _COMMAND="for _I in $*; do echo \$_I; done;"; fi; eval $_COMMAND | while read _FILE; do if test "$_INTERACTIVE"; then echo "$_FILE? "; read _RESP &2 "$0: $_FILE: not a file"; continue; fi; if cp $_FILE $TRASH; then /bin/rm $_FILE; else return 1; fi; done; if test "$_RECURSIVE"; then /bin/rmdir $*; fi; return 0; } discard() { # Written by James Logan (vsedev!logan) 11/88 # Take out the trash hastrash || return 1; case $# in 0) ;; 1) if test "$1" = "-f"; then _FORCE="1"; else echo >&2 "Usage: $0 [ -f ]"; return 1; fi; ;; *) echo >&2 "Usage: $0 [ -f ]"; return 1; ;; esac; if test "$_FORCE"; then /bin/rm -f $TRASH/*; return $?; fi; for _FILE in $TRASH/*; do echo "$_FILE? [y, n, q]:\c"; read _RESPONSE; case "$_RESPONSE" in [qQ]*) return 0; ;; [yY]*) /bin/rm -f $_FILE; ;; [nN]*) continue; ;; esac; done; return 0; } ------------------------------------------------------------------------------- -- Jim Logan logan@vsedev.vse.com (703) 892-0002 uucp: ..!uunet!vsedev!logan inet: logan%vsedev.vse.com@uunet.uu.net