Home page Contact information List of services provided Automation details Perl, Shell, IDL code examples Professional and personal experience Weblog Charities We Support Miscellaneous Info and Links

FTP Backup Program

This backup program can be used without an FTP Server if you just want to run backups to a seperate disk or directory. This is mentioned in the section dealing with the backup.cfg configuration file.

Mike Schienle


There are three sections to making this run, the backup.sh source code, the backup.cfg configuration file, and the crontab entry to run the program at a specified date and time.

Source Code

#!/bin/bash
#-----------------------------------------------------------------------
# Author: Mike Schienle
# $RCSfile: backup.shtml,v $
# $Revision: 1.1.1.1 $
# Orig: 2000/12/10 04:44:42
# $Date: 2004/01/15 00:24:44 $
#-----------------------------------------------------------------------
# Purpose: Backup specified directories to specified locations.
# History: 
#   MGS 01/19/01 23:05:33
#       Added YYYYMM variable for directory nesting on the backup site.
#-----------------------------------------------------------------------
# $Log: backup.shtml,v $
# Revision 1.1.1.1  2004/01/15 00:24:44  mgs
# Checking using generic CVSROOT
#
# Revision 1.1.1.1  2004/01/14 21:31:32  mgs
# Initial Custom Visuals checkin
#
# Revision 1.2  2001/01/20 07:06:24  mgs
# Added YYYYMM variable for directory nesting on the backup site.
#
# Revision 1.1  2000/12/17 16:10:49  mgs
# Initial revision
#
#-----------------------------------------------------------------------

#   read data from the specified file
file="$@"

if [[ $file == "" ]]
then
    cmd=`basename $0`

    cat <<-EOF
    usage: $cmd parameterFile

    parameterFile contains lines with up to 6 parameters per line.
    The parameters are: src dest site usrname pass dir

    src is the top level directory for files to be backed up
    dest is the destination directory to store backed up files
    site is the FTP site name
    usrname is the name of the user on the FTP site
    pass is the password for the user on the FTP site
    dir is the directory to store files on the FTP site

    A directory called stamp will be made in the user's home directory.
    This directory is used to determine changed files from previous runs.
    It will contain empty files named with the date/time that $cmd
    was run.

    The FTP command will be bypassed if there are only src and dest values.

    Samples lines from a parameterFile:
    /Local/Users /tmp aleutian.customvisuals.com backUser backPW backups
    /Local/WebSites /tmp aleutian.customvisuals.com backUser backPW backups

    files are in gzip'd tar format and are named src.datetime.tgz

    You can expand the file using the following command:
    gzip -c -d file.tgz | tar -xf -

    EOF
    exit 1
fi

#   date stamp location
dirStamp=$HOME/stamp
#   data stamp value
dtStamp=`date '+%y%m%d.%H%M%S'`

#   make the stamp directory if necessary
if [[ ! -d $dirStamp ]]
then
    mkdir $dirStamp
fi

#   get the name of the latest date stamp file
fileLast=`/bin/ls -1 $dirStamp | tail -1`
#   touch a new file for next run of this program
touch $dirStamp/backup.$dtStamp

#   check fileLast value
if [[ $fileLast == "" ]]
then
    #   assign empty string to our command
    testLast=$fileLast
else
    #   force command to use files modified after last dtStamp file
    testLast="-newer $dirStamp/$fileLast "
fi

#   specify YYYYMM variable for FTP subdirectory
dateYM=`date '+%Y%m'`

while read src dest site usrname pass dir
do
    #   change to source directory
    cd $src

    #   find all files in source directory
    #   put all file names in a list
    fileBack=`basename $src`

    #   run the find command
    find . -type f -depth $testLast -print > $dest/$fileBack.$dtStamp.txt
    
    #   get the number of files in the backup list
    nFiles=`cat $dest/$fileBack.$dtStamp.txt | wc -l`
    #   echo a status message
    echo $nFiles files from $src on `date '+%D %T'`

    #   if the list of file names is not zero (has some names)
    if [[ -s $dest/$fileBack.$dtStamp.txt ]]
    then
        #   tar and gzip output to $dest directory
        cat $dest/$fileBack.$dtStamp.txt | \
            xargs tar czf $dest/$fileBack.$dtStamp.tgz
    fi
    
    #   change to the destination directory
    cd $dest

    #   ftp the files to the specified site
    if [[ $site != "" ]]
    then
        ftp -in $site <<-EOH
            user $usrname $pass
            bin
            cd $dir
            mkdir $dateYM
            cd $dateYM
            mput *.$dtStamp.*
            quit
        EOH
    fi
done < $file

Configuration File

The configuration file can be placed wherever is convenient. I have mine placed in root's home directory. You can have as many lines as you'd like in the file, they will run sequentially.

/Local/Users /tmp server.domain.com userName passWord backups
/Local/WebSites /tmp server.domain.com userName passWord backups

If you do not want to use an FTP site and have a local or NFS mounted disk or directory where you would like the backup files to be stored, that's also available. Just leave off the last four parameters of the lines in the configuration file and the program will skip the FTP commands. You can have some hierarchies that get backed up to an FTP site, some that go to local disks, and some to NFS mounted disks.

/Local/Users /tmp
/Local/Development /nfs/project/archive
/Local/WebSites /tmp server.domain.com userName passWord backups

Crontab Entry

The last step is to have cron automate the tasks. This is the cron entry for root on my system. The backup.sh command is located in root's bin directory and runs every morning at 12:30 AM, using backup.cfg as its parameter file. backup.cfg is in root's home directory.

30 00 * * * $HOME/bin/backup.sh backup.cfg

You can also have multiple cron entries, with each one using a different configuration file. Or, you can use cron to clear out the stamp directory completely or partially (i.e. files over 1 week old), to allow several levels of backups to be performed. Here are a couple entries I use along those lines.

25 00 1 * * rm -f $HOME/stamp/*
25 00 14,28 * * rm -f `find $HOME/stamp -type f -mtime -7`     

The first entry removes all the stamp files from the stamp directory on the first day of each month. The second entry removes files less than 7 days old on the 14th and 28th of each month so I can get a different backup level. I also have a crontab entry that removes files from the destination directory on a regular basis so it doesn't get filled up with old files.


Home Contact Services Automation Code Background Weblog Charity Other

backup.shtml was last updated on Friday, 04-Nov-2005 07:18:52 CST