allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc) (06/04/89)
Posting-number: Volume 7, Issue 14 Submitted-by: naz@hslrswi.UUCP (Norman H. Azadian) Archive-name: scavenge.ksh Here is a tool I use on my PC running under the MKS Toolkit. This shell script could presumably be adapted quite simply to run under any unix, although the need for it would be less on a real unix. [You think. Of course, most people on the Usenet are intelligent enough not to install applications in /tmp; the people *I* have to hand-hold aren't. Cleaning up /tmp is a real project on *their* systems. ++bsa] Being the cautious type, I generally put unwanted files in /tmp. Later, when I need disk space, I run this tool to actually delete the oldest of those files. It also knows enough to look in other places where I keep old, expendable, files. As a cautious type, I've built in all manner of safeguards and options to allow me to see what's going to be deleted, and to give me a veto. The basic operation of the tool, however, is quite simple. When invoked with no argument, it reports the number of KBytes which could be recovered by deleting old files. When invoked with a number, it will delete just enough old files to increase the available disk space by that many KBytes. The -L option allows you to review the list of termination candidates, using the pager named in your PAGER environment variable. Failing such a variable, it will use a default. I currently have the default set to my own hacked version of less. A more reasonable choice for most people would be the pg.exe program that comes with the toolkit. BUG NOTE: It is supposed to delete the files in chronological order. In my version 2.2d of the Toolkit, the -t option of ls does not work correctly, and so files are not deleted in chronological order. If you have a newer version, it might work for you. #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # scavenge.ksh # This archive created: Thu May 25 14:28:15 1989 # By: Norman H. Azadian (Hasler AG) export PATH; PATH=/bin:$PATH echo shar: extracting "'scavenge.ksh'" '(5625 characters)' if test -f 'scavenge.ksh' then echo shar: will not over-write existing file "'scavenge.ksh'" else cat << \SHAR_EOF > 'scavenge.ksh' # /usr/bin/scavenge.ksh 890523 NHA # With no parameters, simply reports the number of KBytes in expendable files. # With 1 parameter, prepares a list of temporary files to delete such that # that number of KBytes will be freed up on the disk. # The -Fspec option allows the user to prepend filespecs to fileSpec. # The -I option makes the selection process Interactive. # The -L option shows the list of files that can/will be deleted. # The -V option makes all output verbose. # Exit status is always 0 for success, otherwise 1. # At present only the last filespec suggested by the user will be processed. # Files are selected for deletion in line with the following priorities: # 1) minimize the number of directories (filespecs) affected. # 2) maximize the age of the files deleted. ##NOTE THAT IN VERSION 2.2D OF THE TOOLKIT, THE -T OPTION OF LS IS BROKEN. ##THEREFORE THE ORDER OF DELETION MIGHT NOT BE OPTIMAL. # User-definable constants ##typeset defaultPager='pg' ##typeset defaultPrompt='-p__h_for_help,___q_to_continue_______________Page_%d' typeset defaultPager='less -aVh_for_help,___v_to_edit,___q_to_continue' typeset defaultPrompt='-aVh_for_help,___v_to_edit,___q_to_continue' #filespecs must be put in an array, one spec per array element. typeset fileSpec fileSpec[1]='/tmp/*' fileSpec[2]='/file[0-9][0-9][0-9][0-9].chk' fileSpec[3]='/usr/obsolete/*' # Internal constants and variables typeset -i blocksPerKByte=2 #2 blocks per KByte typeset -i Vopt=0 Iopt=0 Lopt=0 # -V and -I and -L option flags typeset masterList=/tmp/__scav__.tmp #master list of gleanable files typeset tmpFile=/tmp/__temp__.tmp #temporary file typeset usrFileSpec=" " #user filespec gets stashed here #parse command line typeset -i requested=0 for arg do case $arg in -[iI]) Iopt=1 ;; -[vV]) Vopt=1 ;; -[fF]*) usrFileSpec=${arg#-[fF]} ;; -[lL]*) Lopt=1 ;; [0-9]*) requested=$arg ;; *) cat <<-\FOOBIE_BLETCH scavenge -- free up disk space by deleting temporary files usage: scavenge [-Fspec] [-I] [-L] [-V] [kbytes] -Fspec spec is pre-pended to list of expendable filespecs -I Interactive file selection -L List of eligible files is shown -V Verbose outputs kbytes number of KBytes to recover. default 0 If kbytes is not given, nothing will be deleted. FOOBIE_BLETCH exit 1 ;; esac done ##echo "Iopt=$Iopt Lopt=$Lopt Vopt=$Vopt requested=$requested" #initialize master listing file if test $Lopt -ne 0 -a $Vopt -ne 0 then echo 'BLKS PERMISSION LNK BYTES DATE TIME FILENAME' >$masterList echo '==== ========== == ====== ====== ===== ========================================' >>$masterList else rm -f $masterList fi #Draw up the master list of candidates. # "If one day it should happen that a victim must be found," # "I've got a little list..." -- Lord High Executioner from "The Mikado" # first the user-suggested filespec if test -r `echo $usrFileSpec | cut -d" " -f1` then #build sorted list | remove "total" line | remove directories ls.exe -trlsd $usrFileSpec | egrep -v '^total [0-9]+' | \ egrep '^[\ 0-9]+\ \-' >>$masterList fi # then all the built-in filespecs typeset -i i=1 while (( i < ${#fileSpec[*]} )) do if test -r `echo ${fileSpec[i]} | cut -d" " -f1` then #build sorted list | remove "total" line | remove directories ls.exe -trlsd ${fileSpec[i]} | egrep -v '^total [0-9]+' | \ egrep '^[\ 0-9]+\ \-' >>$masterList fi let i=i+1 done #Handle the -L option if test $Lopt -ne 0 then if test -z "$PAGER" then $defaultPager $defaultPrompt $masterList else $PAGER $masterList fi if test $Vopt -ne 0 then #get rid of header lines tail +2 $masterList >$tmpFile mv $tmpFile $masterList fi fi typeset blocks permissions links month timeYear name reply typeset -R8 bytes typeset -R2 day typeset -i neededBlocks neededKB #Handle case where only a report is wanted. if ((requested == 0)) then while read -r blocks permissions links bytes month day timeYear name do ((neededBlocks = neededBlocks + blocks)) done <$masterList ((neededKB = neededBlocks / blocksPerKByte)) if ((Vopt == 0)) then echo $neededKB else echo "$neededKB KBytes are eligible for scavenging." fi exit 0 fi #bail out if there's nothing available if test ! -s $masterList then if test $Vopt -ne 0 then echo "scavenge: no files to scavenge." fi exit 1 fi #Now for the delicate task of deciding who gets the axe. neededBlocks=`expr $requested '*' $blocksPerKByte` while test $neededBlocks -gt 0 do while read -r blocks permissions links bytes month day timeYear name do if test $Iopt -ne 0 then if test $Vopt -ne 0 then echo "Delete $bytes $month $day $timeYear $name\t[Nyq] ? \c" else echo "$name\t[Nyq] ? \c" fi reply=`line` </dev/con reply=${reply:=No} #empty line means "No" else reply=Yes fi if test -z "${reply##[qQ]*}" then break; #bail out fi if test -z "${reply##[yY]*}" then ((neededBlocks = neededBlocks - blocks)) if test $Vopt -ne 0 then let 'neededKB = neededBlocks / blocksPerKByte' echo "deleting $name -- $neededKB KBytes to go" fi rm $name if test $neededBlocks -le 0 then break fi fi done <$masterList if test $Vopt -ne 0 -a $neededBlocks -gt 0 then neededKB=`expr $neededBlocks '/' $blocksPerKByte` echo "scavenge: still need to eliminate $neededKB KBytes" echo "scavenge: hit carriage return to continue, ^C to quit" line else exit 0 fi done SHAR_EOF if test 5625 -ne "`wc -c < 'scavenge.ksh'`" then echo shar: error transmitting "'scavenge.ksh'" '(should have been 5625 characters)' fi fi # end of overwriting check # End of shell archive exit 0 NHA === PAPER: Norman Azadian; Hasler AG; Belpstrasse 23; 3000 Berne 14; Switzerland X.400: naz@hslrswi.hasler UUCP: ...{uunet,ukc,mcvax,...}!cernvax!hslrswi!azadian VOICE: +41 31 63 2178 BITNET: naz%hslrswi.UUCP@cernvax.BITNET