#! /bin/sh # O Muse! We begin # with ancient incantations # to sing our song well. # (It means, 'use this shell.' # I know it looks funny, but # UNIX is like that.) # Cryptic UNIX strings # like "hash bang slash bin slash sh" # save keystrokes, and wrists. # No one likes typing # the same thing over and over, # so files get short names. # Take these hashes (please!) # adorning my measured lines: # they say, comments here! # This is a shell script. # It moves files from place to place, # backups = peace of mind. # (I know I cheated # there; keystrokes and syllables # are in short supply. # O muse, we'll never # get anywhere if I can't # use symbols, forgive.) # Onward we must go. # Line by line, the file is read; # No GOTO 10 here. # These lines are for you, # dear reader; the shell doesn't # read our verse. Pity. # Let's start at the top. # I use this script, it's for me; # Your miles WILL vary. # (I run on a Mac. # Linux users might find the # filenames quite strange. # But Macs run UNIX! # Darwin kernel with launchd; # hark, the angels sing.) # A universal # truth, like land wars in Asia: # all drives will fail. # But Moore's Law saves us. # You can get hard drives for less # than a good latte. # Simple strategy: # Toss your data to the wind, # across many disks. # Onsite, offsite, pshaw! # They're all the same to our law. # Enough rhymes! Let's talk. # Backups are snapshots # of a host through time. One's good; # three is divine. # Archives lack a host. # Like Goa'uld or Trill, they # live on network drives. # Mirrors do their task, # spreading data around like # beads at mardi gras. # You could also say # Archives are fixed, permanent; # Backups use --delete. # So: three drives you need. # Backup should be big, Archive # and Mirror equal. # Did I mention speed? # Get Firewire or we'll # be at this all day. # There are two flavors # (sweet!) of this fast protocol: # Four hundred, and eight. # USB 2's fine # if that's all your machine has. # 1.1's too slow. # I know how this sounds. # Trust me, though. You've more data # than even you know. # Let's declare our terms, # give our chant some form and flow # (and keep our typing --) tdy=`date +%Y-%m-%d` host=`hostname -s` user=`id -un` # Did you notice it? # No apostrophes for us!! # Look under the ~ -- # Backticks tell UNIX # 'take this output as a string' # `command me, oh muse.` # Now let's name our drives. # We'll use these later, when we # see if they're attached. adrive=/Volumes/Archive bdrive=/Volumes/Backup mdrive=/Volumes/Mirror sdrive=/Volumes/Secure # See? That wasn't hard. # I'm a better poet than # programmer. (You're doomed.) # Now on to backups. # Set your drive structure up here. # (Brute force, save the day!) # My backup drive # is > 3x my laptop's size. # So I'll arrange it so: backup=$bdrive/$host/ last=$backup/Users/ old=$bdrive/Old/$host/Users/ older=$bdrive/Older/$host/Users/ # Why use $host? Easy: # Other machines use this drive. # $host keeps them apart. excludes=~/bin/backup/excludes # "excludes" is a file # that we'll use later on to # step around problems. use_offsite=yes offsite=~/bin/backup/offsite # Our variables, # I do declare, are declared. # Whitman would be proud. # Before we go on, # check the map to see what's there. # "if test" is my friend. if test -d $bdrive then if test -d $old then # move 1 into 2 # For backups, rsync # does what we need; only changes # are replicated. # We're moving things back # from old to older (brute force) # No elegance here. mkdir -p $older rsync -avzx -E --progress --delete $old $older # A word on those flags: # "archive, verbose, zip, stay here," # and "secret Mac stuff." # "Dash e" and "dash E" # weren't separated at birth. # Homonyms, that's all. # Resource forks are hell # when going across systems. # Black magic, I guess. # So "dash E" for Macs # on journaled HFS+ # volumes only, please. # What were we doing? # Oh right, backing up data. # Oldest stuff's now gone. fi # Let's do it again! # Moving through time is easy, # one direction only. # Last backup's so then, # get it out of our sight. To # Old/ it goes, cruel eld. if test -d $backup then mkdir -p $old rsync -avzx -E --progress --delete $last $old # Did you follow that? # Watch: "Last" goes to "Old" goes to # "Older" goes to ... null. # (If I were clever # I'd come up with better names, # but this works for me. # Important advice: # know when good is good enough. # Move on with your life.) fi # Now on to our drive. # Duplicate precious data! # (finally, you sigh.) rsync -avzx -E --progress --delete --exclude-from $excludes / $backup # OMG we're done? # I never thought we'd get here: # "Backup is complete." echo "Backup is complete." fi # If $bdrive's not there # you skipped that whole bit; don't fret. # There's always next time. # Now it's archive time. # We'll check to make sure it's there # before we go on. if test -d $adrive then # Mirror mirror on # the wall, did you ever think # you'd reflect bytes? if test -d $mdrive then rsync -avzx -E --progress --exclude ".Trashes/" --exclude ".Spotlight-V100/" --delete $adrive $mdrive # That's it for Mirror. # What can I say? It has one # purpose: Save Archive. # You may ask yourself, # why are we mirroring now? # Two words: "Murphy's Law." fi # This next bit's easy. # Although, I've said that before. # (Perhaps I was wrong?) # All my archive scripts # dump their output in one # location: ~/Archive/ # So here at the end # it doesn't matter what's run, # we just grab it all. rsync -avz -E --progress ~/Archive/ $adrive/ # Our media is next, # separate copies we'll keep. # (Again, no --delete.) rsync -avz -E --progress --exclude "Podcasts/" ~/Music/iTunes $adrive/Media/ # rsync -avz -E --progress ~/Pictures/iPhoto\ Library $adrive/Media/ rsync -avz -E --progress ~/Sites/myPhoto/iPhoto\ Library $adrive/Media/ fi # That's it. We are done. # Data scattered like petals. # I thank you, O muse. # 2007-03-22: Version 1.0 published. # Referenced at http://brettpeters.org/docs/backup.html. # (c) Brett Peters. All rights reserved, no warranty. Use at own risk.