Monday, January 28, 2008

Trash Management Scripts

Moving files to trash



Today's post is about some trash management scripts I have written for myself and would like to share. They should run on most GNU+Linux environments.


If you're like me, you prefer to mv file ~/.Trash/ rather than rm file, but this is both dangerous and hard to type. I created a (very small) script that will act as a command you can use to move files to your Trash bin without overwriting anything.


Uses 'numbered' backup scheme of 'mv', so the most recently trashed
file will have its name intact, and the backups will have the suffix
".~n~" appended, where the higher the n, the more recent the backup.



#!/bin/sh
#
# Moves files in the command arguments to the trash bin, while keeping
# backups of any files already in that directory.
#
# Uses 'numbered' backup scheme of 'mv', so the most recently trashed
# file will have its name intact, and the backups will have the suffix
# .~n~ appended where the higher the n, the more recent the backup.
#
# It uses the basename of the file so that no (absolute or relative)
# directory is preserved.
#
TRASH="$HOME/.Trash";

while [ $# -gt 0 ];
do
mv --backup=numbered "$1" "$TRASH/`basename $1`";

shift;
done


After you copy this file to your favorite bin directory and make it executable, you can use the following syntax

trash file1 file2 path/to/file3 path/to/file4

And, even if file1 and file3 have the same name, you'll still be able to find both in your trash bin.


Rounding up and deleting trash automatically



If your trash is anything like mine, the probability that a file is not trash increases exponentially every day. For this reason, I wanted to somehow tag when I threw something out so I could tell how old it was, and maybe delete everything after a specific number of days.


The solution I came up with was to create siblings of the .Trash directory, using UNIX time-stamps. In conjunction with a cron task, yesterday's trash will be in a directory at ~/.Trash-XXXXXXXXXX where the X's are the time-stamp for 4:00am today. In this manner, you'll have a bin for each day you throw something out. The script follows.



#!/bin/sh
#
# The first step is to move all files under ~/.Trash, other than
# ., .., and .#bin-n into a new trash bin for yesterday.
#
#

NEWBIN=`date +%s`;
NEWBINPATH="$HOME/.Trash-$NEWBIN";
OLDESTBIN="20"; # days

OLDESTBINTIME=`date -d "now - $OLDESTBIN days" +%s`;
OLDESTBINPATH="$HOME/.Trash-$OLDESTBINTIME";

echo "Moving current trash to $NEWBINPATH";
mkdir $NEWBINPATH;
mv $HOME/.Trash/* $HOME/.Trash/.[!.]* $NEWBINPATH/;

for BIN in $HOME/.Trash-*; do

STAMP=`echo "$BIN" | cut -d'-' -f2`;
# echo $BIN $STAMP $OLDESTBINTIME;
if [ $STAMP -lt $OLDESTBINTIME ] ;
then
echo "Deleting $BIN";
# rm -Rf $BIN;
fi

done


So I copied this file into my ~/bin/ directory and used crontab -e to add the following line to my crontab:

00 4 * * * /home/ryan/bin/trash-roundup.sh


Right now this script will send errors to crond, which should be delivered in your local mail (accessed using mail). Also, deleting old bins is disabled since I haven't had a chance to thoroughly test it.


To actually delete old trash, choose a value for the OLDESTBIN variable in the script, this is the longest time that a bin will hang around. Then, you have to un-comment the line with rm in the script.

No comments: