rm eating everything, here’s a bit of my solution

Everyone’s who’s worked in a computer environment which assumes you know what you’re doing knows that you don’t in fact always know what you’re doing. So I like a couple of things to be true. First, I want the machine to do what I say when I say it. Second, I want to be able to undo whatever it is I just did when I realize I just deleted a bunch of critical files. My solution to this comes in a few parts. First, I make a trash folder which holds files on the way out. Second, when I say rm, I actually just move those files to the trash folder, which is very fast. Then later, I zip the files in the trash, so while they’re sitting there they don’t take up any space. Now the file is gone from the working directory and most of the space is reclaimed. And if I need the file back I know where to look to get it. I might need to unzip it, but it’s there. And I never need to empty the trash, because every day those files older than 30 days old go buh-bye. So machinery which lets me recover files, doesn’t slow anything down, and requires no maintenance. Check. I might recommend testing everything on the command line before you let if loose.

First, make a trash directory, on ubuntu one is made for you, namely ~/.local/share/Trash/files/ . I put this in my .bashrc

export TRASH=”~/.local/share/Trash/files/”

though of note I use the full path here. I think because of the way we’re going to use bash substitutions it needs to be a full path. I replace rm with my own version, which lives in ~/bin/ which is in the path before the real rm.

#!/usr/bin/perl
# safer rm
use strict;
my $carg;
my $cmd;
my $trash = $ENV{'TRASH'};
if($trash eq "")
{
     print "\$TRASH is empty string. exiting";
     exit(0);
}
for(my $i=0; $i < $#ARGV+1; $i++)
{
     $carg = $ARGV[$i];
     $carg =~ s/\/$//g;#does what?
     if(!(-e $carg)){next;}
     system("touch $carg && /bin/rm -rf $trash/$carg; mv $carg $trash");
}

I make two additions to the crontab:
30 3 * * * empty_trash
*/30 * * * * zip_trash

and then there’s empty_trash and zip_trash:
#!/bin/bash
# empty_trash
if [ "$TRASH" == "" ]; then
     echo '$TRASH is not set, bailing.'
     exit
else
     find $TRASH -xdev -mindepth 1 -mtime +14 -print0|xargs -P 2 -n 10 -0 --no-run-if-empty /bin/rm -r
fi

#!/bin/bash
# zip_trash
if [ "$TRASH" == "" ]; then
     echo '$TRASH is not set, bailing.'
     exit
else
     find $TRASH -mindepth 1 -xdev -type f -print0 |xargs --null -P 7 -n 1 --no-run-if-empty nice -n 19 gzip -f -q 2>&1
fi

Advertisements

Daily Archiving

It’s a good idea. Do it. It doesn’t need to be a hassle. If you have a ‘nix system you can tweak this script to suit your tastes. Pretty much you’ll need to edit the excluded directories. I don’t backup thunderbird because it’s all on the imap, or the trash, well because there’s nothing there I care about, hence calling it the trash. And a few other things I don’t really hold near and dear. This one will keep the last 3 days on hand, as well as one archive per week for the last month, and keeps monthlies for a long time. Feel free to edit, and share, CC-BY-SA (you can put Bearfeet, for the by).

#!/usr/bin/perl
# created 9/2010 by Bearfeet
use strict;
system(“chmod 755 ~/Archives/”);
my $date = `date +%Y_%m_%d`;
chomp($date);
my $home = `echo ~`;
chomp($home);
chdir $home;
my $host = `hostname`;
chomp($host);
my $ehome = $home;
$ehome =~ s/\//\\\//g;
my $archive = “$host\_backup_$date.tar.gz”;
my $command = “ls -A1 ~|grep -Ev \”Archives|remote_drives|Trash|Music|thumbnails\”|”;
$command = “$command xargs -r tar -czf $home/Archives/$archive”;
$command = “$command –exclude=\”*[Cc]ache*\””;
$command = “$command –exclude=\”*macromedia*\””;
$command = “$command –exclude=\”.wine\””;
$command = “$command –exclude=\”share/Trash\””;
$command = “$command –exclude=\”.VirtualBox\””;
$command = “$command –exclude=\”.thunderbird\””;
$command = “$command –exclude=\”Downloads\””;
$command = “$command 2>/dev/null”;
system($command);#create today’s archive
my $offset = `date +%d`;
if($offset == 1)
{
print “first condition\n”;
$offset = `date –date=”+10 years -3 days”`;
system(“touch –date=\”$offset\” $home/Archives/$archive”);
}
elsif($offset%7 == 1)
{
print “second condition\n”;
$offset = `date –date=”+1 month -3 days”`;
system(“touch –date=\”$offset\” $home/Archives/$archive”);
}
system(“find $home/Archives -mtime +3 -name \”$host\_backup_*_*_*.tar.gz\”|xargs -r /bin/rm”);#|xargs /bin/rm”);
system(“chmod 555 ~/Archives/”);