burdick@hpindda.HP.COM (Matt Burdick) (11/04/88)
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? Right now, I have an alias that does this, but the problem is that may alias doesn't handle all of rm's flags. For instance, it complains if I type in 'rm -rf *', since 'mv' doesn't have the -r flag and also can't move across file partitions. -- Matt Burdick | Hewlett-Packard burdick%hpda@hplabs.hp.com | Technical Communications Lab
maart@cs.vu.nl (Maarten Litmaath) (11/05/88)
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?
\
\Right now, I have an alias that does this, but the problem is that may
\alias doesn't handle all of rm's flags. For instance, it complains if I
\type in 'rm -rf *', since 'mv' doesn't have the -r flag and also can't move
\across file partitions.
How about the following csh hacks?
You needn't use the `-rf' flags anymore, just type `rm directory'!
alias rm 'set r=(\!* /); _rm'
alias _rm 'if ($#r > 1) eval /bin/mv $r[1] ~/tmp \|\|'\
'/bin/cp -r $r[1] ~/tmp \&\& /bin/rm -r $r[1]\; shift r\; _rm'
--
George Bush: |Maarten Litmaath @ VU Amsterdam:
Capt. Slip of the Tongue |maart@cs.vu.nl, mcvax!botter!maart
tondu@felix.UUCP (Walter Tondu) (11/06/88)
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? > >Right now, I have an alias that does this, but the problem is that may >alias doesn't handle all of rm's flags. For instance, it complains if I >type in 'rm -rf *', since 'mv' doesn't have the -r flag and also can't move >across file partitions. > >-- >Matt Burdick | Hewlett-Packard >burdick%hpda@hplabs.hp.com | Technical Communications Lab Here's a solution which I use. This comes from "Tricks of the UNIX Masters" by Russel G. Sage. Published by Howard W. Sams & Co. I have modified it a tad in order to fit my needs more exactly usage: 1) rm -l; - lists all files that have been removed to - 'can' directory. 2) rm -r; - remove permanently all files that have been - previously removed. 3) rm -f; - use /bin/rm and force removal. (strip following code of leading "*". *: *# @(#) can v1.0 Maintain trash can * *CAN=$HOME/.trashcan * *#if [ ! d $CAN ] *#then *# mkdir $CAN *#fi * *if [ $# -eq 0 ] *then * echo "usage can [-l] [-r] [-f] file [file ...]" >&2 * exit 0 *fi * *if [ "`echo \"$1\" | cut -c1`" = "-" ] *then * case $1 in * -l) echo "$CAN:" * /bin/ls $CAN * exit 0;; * -r) echo "removing $CAN/*:" * /bin/rm -rf $CAN/* * exit 0;; * -f) echo "force removal" * /bin/rm -rf $@ * exit 0;; * -?) echo "usage can [-l] [-r] file [file ...]" >&2 * exit 0;; * esac *fi * *mv $@ $CAN ____________________________________________________________ .plan - to indulge whenever possible walter tondu ____________________________________________________________
marki@hpiacla.HP.COM (Mark Ikemoto) (11/06/88)
Try this. It runs a little too slow for me but maybe you're running on a faster machine. ( Matt, for the b_on, b_off, u_on, u_off script variables, you'll need to replace <esc> with the real escape character so the bolding will work on your HP terminal. I deliberately used <esc> so other people's non-HP terminals accessing Notes wouldn't get screwed up by the escape chars when they looked at this script. ) Mark ------------ CUT LINE: Remove this line and everything above it ------------ # Bourne shell script ####################################################################### # # @(#) TITLE: Safer rm command # # # DESCRIPTION: See user man page below. # # INSTALLATION: # # Save this to a file. Change user-defined shell vars after the # script header to your taste and terminal. Set the permissions on # this script to 'execute'. Invoke this script with no parameters # to see the embedded man page. # # UPDATE HISTORY: # # what date/who type of change # ---- -------- -------------- # 01/18/88 # Mark Ikemoto >Script created. # # 03/03/88 # Mark Ikemoto >Added touch command to give file the current time # so it isn't cleaned up until it is older than the # system backup timestamp file. # # @(#) 11/05/88 # Mark Ikemoto >Added much more comments. # >Added pseudo support for the -f option. # >Isolated HP terminal escape chars into shell vars. # ####################################################################### # Shell user-defined functions # #################################################################### # Start of main commands # #------------------------------------------------------------------- # USER MUST SET THESE VARIABLES FOR INSTALLATION OF THIS SCRIPT # USER MUST SET THESE VARIABLES FOR INSTALLATION OF THIS SCRIPT # USER MUST SET THESE VARIABLES FOR INSTALLATION OF THIS SCRIPT # junkdirname="$HOME/.rmfiles" # name of user junk file subdir rmlogfile="rmlogfile" # list of removed files # bolding/underlining for error messages and for keywords in the # man page... b_on='<esc>&dB' # set bolding on for HP terminal b_off='<esc>&d@' # set bolding off for HP terminal u_on='<esc>&dD' # set underlining on for HP terminal u_off='<esc>&d@' # set underlining off for HP terminal # For other types of terminals, substitute appropo # terminal char sequences or just set b_on, b_off, # u_on, u_off to empty (''). #------------------------------------------------------------------- # Initialize some global vars # PATH=/bin:/usr/bin:/usr/contrib/bin:/usr/local/bin:/etc:. TZ=PST8PDT; export TZ # set time zone for invocations of cmds like date, etc. options= export options fname=`basename $0` cap_fname=`echo $fname | tr "[a-z]" "[A-Z]"` # make filename uppercase cmdline=$* # used in help-checking later on # default settings: overwrite='false' # force overwriting; don't prompt for user verify? interactive='false' # user wants to verify copy for each source file? removedir='false' # user wants to remove a subdir? default = no. #------------------------------------------------------------------- # Set up some traps for signals. NOTE that any shell variables used # in the trap routine must have been defined previous to this trap # declaration. # trap "echo $cap_fname: Type $fname -h\<ret\> for help.'; exit 2" \ 1 2 3 6 7 15 #------------------------------------------------------------------- # Grab args from command line # set -- `getopt ifrh $*` # check if a valid command line entered if [ $? -ne 0 ] then echo "$b_on $cap_fname: Bad runstring option.$b_off" echo "$b_on Type $fname -h<ret> for help.$b_off " exit 2 fi #------------------------------------------------------------------- # Parse command args # help_wanted=false while [ $# -gt 0 ] do case $1 in -i) interactive='true';; -f) ;; -r) removedir='true';; -h) help_wanted='true';; --) shift; break;; # end of options in command line; # source/target names should remain in runstring *) echo "$b_on $cap_fname: Bad runstring option.$b_off " echo "$b_on Type $fname -h<ret> for help.$b_off " exit 2;; esac shift done #------------------------------------------------------------------- # Does user want a help screen? # if [ -z "$cmdline" -o "$help_wanted" = 'true' ] then more <<! $b_on NAME$b_off $cap_fname -- Safer rm command $b_on SYNOPSIS$b_off $b_on $fname [-i] [-f] [-r <subdir>] <file> ... $b_off $b_on $fname -h$b_off $b_on DESCRIPTION$b_off A safer rm command. Will "delete" files/subdirs and move them to a user "junk file" subdirectory. The current junk dir name being used is $b_on $junkdirname $b_off . This junk dir name is hardcoded into this script. This script assumes that the junk dir already exists before calling this script. The $u_on arguments$u_off are: $b_on <-i>$b_off will cause $fname to obtain authorization from the user before removing each source file. $b_on <-f>$b_off does absolutely nothing and is only accepted for compatibility with the real rm's runstring options. $b_on <-r>$b_off will cause $fname to remove the subdir specified in the runstring. The subdir tree structure is moved to the junk file subdir intact before the source subdir is removed. $b_on <file> ...$b_off are the names of the files/dirs to delete. $b_on -h$b_off will cause this help screen to be displayed. This is the same as typing $fname <ret> with no parameters. Files deleted can be unremoved by the user; the unremoval must be done by hand (sorry). This is because the user might have removed several files with the same name and the user would have to go into each file anyway to figure out which is the file that they want to unremove. When a file/dir is moved to the junk directory, it is renamed with a unique filename so that future rm'ing of files with the same name will not cause files in the junk directory to be overwritten. However, if all of the removed files in the junk directory have unique, non-user-friendly names, then the user will have a heck of a time trying to figure out which file is the one they want if they want to restore a file. So, before files are renamed during the remove process, their original name and their new unique name will be placed as an entry in a listing file, $b_on $junkdirname/$rmlogfile $b_off , along with a prefix, 'f' or 'd', to indicate whether the entry is a removed file or directory, respectively. Note that once a file/dir has been unremoved, its entry in the listing file still exists. The user must remove their entry from this listing by hand (sorry again). $b_on WARNING$b_off This script is not portable because of the use of HP terminal escape sequences in the man page and error messages. You must alter script shell vars to make this portable. $b_on AUTHOR$b_off HP R&D Lab. ! exit 0 fi # #---------------------------------------------------------------------- # Do the main loop while [ $# -gt 0 ] do if [ "$interactive" = 'true' ] then echo "Remove $1? (y/n/a[bort]) \c" read answer if [ "$answer" = 'a' ] then exit 0 fi if [ "$answer" != 'y' -a "$answer" != 'Y' ] then shift # go on to next source file name continue fi fi if [ -d "$1" ] then if [ $removedir != 'true' ] then echo "$b_on $cap_fname: Specified directory removal of $1$b_off " echo "$b_on but remove-dir option (-r) not specified.$b_off " echo "$b_on Type $fname -h<ret> for help.$b_off " shift continue # bypass this name; go to the next one fi # create a subdir inside the junk file subdir in which to # deposit "removed" subdir file(s) # rmname="`expr substr $LOGNAME 1 4``date +%m%d%H%M%S`" mkdir $junkdirname/$rmname touch "$junkdirname/$rmname" # give file the current time to aid in # cleaning up the junk dir using this timestamp cp -r $1 $junkdirname/$rmname /bin/rm -r $1 echo "d $1 $rmname" >> $junkdirname/$rmlogfile else rmname="`expr substr $LOGNAME 1 4``date +%m%d%H%M%S`" /bin/mv $1 "$junkdirname/$rmname" touch "$junkdirname/$rmname" # give file the current time to aid in # cleaning up the junk dir using this timestamp if [ $? != 0 ] then echo "$b_on $cap_fname: Cannot access file/subdir $1 .$b_off " echo "$b_on Consult man pages or$b_off " echo "$b_on type $fname -h<ret> for help.$b_off " exit 1 fi echo "f $1 $rmname" >> $junkdirname/$rmlogfile fi shift done exit 0 # removal complete ####################################################################### # IMPLEMENTATION NOTES/ENHANCEMENT REMINDERS: # # 1. I was giving some consideration into making this a C program so that # it would run faster. Currently, it is too slow for my tastes. # # Note that one problem in making this thing run faster would be in # timestamping the files uniquely, especially if you are copying/renaming # several short files all at the same time. The system clock would # not have enough opportunity to change to a unique set of digits. # # 2. Instead of uniquely identifying duplicately-named removed files via # timestamping in the filename, how about keeping the names the same # as the originals as much as possible but adding number suffixes if # removing duplicately-named files. This eliminates the need for # an rmlogfile to map timestamped names to real names. # # 3. We give the removed files the current mod timestamp so the files' # mod timestamp could be used by some sort of cleanup script to do # periodic cleanup of the junk dir. Maybe the cleanup script could # be run during login. # # 4. If I had more time, I could develop an 'unrm' command script that, # when invoked with the name of the file/dir to unremove, would # look in the removed-file listing and display all entries matching # the user-specified filename. We could provide unique sequence # numbers for each entry, so that the user, after seeing the display # of candidate entries, could specify the index number of the # entry to unremove. # # This script would remove the entry from the listing after # after completion of the removal of the file/dir itself. # # The other problem that must be overcome is that even if we display # the candidate list entries to the user for unremoval, the user still # may not be able to tell which file is which if there are several # entries with the same original file name. The fix for this would # be to allow the user during rm'ing to specify a comment to be added # to the list file entry for that file. When the user asks to # unremove a file and is shown the list entries of possible candidates, # the user will also see the comment field for each entry. #
logan@vsedev.VSE.COM (James Logan III) (11/06/88)
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 </dev/tty; case "$_RESP" in [Yy]*) ;; *) continue; ;; esac; fi; if test ! -f "$_FILE"; then echo >&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
gwyn@smoke.BRL.MIL (Doug Gwyn ) (11/10/88)
>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? I don't know why you don't want the command that removes links to inodes to do anything other than remove links to inodes. However, you might consider using the Adventure shell I posted a few years ago. It supports resurrection of objects that had been destroyed (sent into limbo).
jerryp@cmx.npac.syr.edu (Jerry Peek) (11/28/88)
In article <67991@felix.UUCP> tondu@felix.UUCP (Walter Tondu) writes: - In article <4460006@hpindda.HP.COM> burdick@hpindda.HP.COM (Matt Burdick) writes: - Here's a solution which I use. This comes from "Tricks of the UNIX - Masters" by Russel G. Sage. Published by Howard W. Sams & Co. - I have modified it a tad in order to fit my needs more exactly - if [ "`echo \"$1\" | cut -c1`" = "-" ] - then - case $1 in - -l) echo "$CAN:" - /bin/ls $CAN - exit 0;; - -r) echo "removing $CAN/*:" - /bin/rm -rf $CAN/* - exit 0;; - -f) echo "force removal" - /bin/rm -rf $@ - exit 0;; - -?) echo "usage can [-l] [-r] file [file ...]" >&2 - exit 0;; - esac - fi Geez. I don't have "Tricks of the UNIX Masters," and maybe that wasn't the original script from the book, but it seems like that section of the code would be a lot more efficient without the (redundant) echo/cut/test. And it doesn't handle the -f case too well because the $@ picks up the -f. Here's a quick hack (not tested, but should work) with a few more fixes, too: case "$1" in -l) echo "$CAN:" /bin/ls $CAN ;; -r) echo "removing $CAN/*:" /bin/rm -rf $CAN/* ;; -f) echo "force removal" /bin/rm -r $@ # PASSES rm THE -f FROM $1 ;; -?) echo "usage can [-l] [-f] [-r] file [file ...]" >&2 exit 1 ;; esac exit 0 Not to be picky here, but I think that a script that you use as much as "rm" should be as efficient as you can make it... --Jerry Peek, Northeast Parallel Architectures Center, Syracuse, NY jerryp@cmx.npac.syr.edu +1 315 443-1722
wu@spot.Colorado.EDU (WU SHI-KUEI) (11/29/88)
In article <844@cmx.npac.syr.edu> jerryp@cmx.npac.syr.edu (Jerry Peek) writes: >In article <67991@felix.UUCP> tondu@felix.UUCP (Walter Tondu) writes: >- In article <4460006@hpindda.HP.COM> burdick@hpindda.HP.COM (Matt Burdick) writes: >- Here's a solution which I use. This comes from "Tricks of the UNIX >- Masters" by Russel G. Sage. Published by Howard W. Sams & Co. >- I have modified it a tad in order to fit my needs more exactly etc., etc. Just another example of the fact that the proper title of the book is: "Tricks of the UNIX Masters, Junior Grade" ^^^^^^ ^^^^^ In reality: Carl Brandauer uunet!nbires!bdaemon!carl