#!/bin/ksh # Author: David Morris # Version: $Id: shiplog.ksh,v 1.2 2004/11/05 20:50:48 davey Exp $ # Purpose: This script was designed to take care of tranferring Oracle # archive files to an offsite server. # To run unattended (e.g. via cron) will need to make sure that # you have SSH set to allow login via a key either with no password # or you have keys pre-loaded with the ssh-agent # # Notes: PATH has to be set to include /usr/local/bin because if it's not # there then the commercial scp2 couldn't seem to find ssh to call it. # (I think this may only be a problem for commercial ssh?) # # License: Released under the GNU Public Licence (GPL) # The terms of the GPL are available at: # http://www.gnu.org/licenses/gpl.html export PATH=$PATH:/usr/local/bin export DIRECTORY=/logfiles # $ARCHIVEFILESPEC should be a pattern for the name of file # that you want to ship. In this case we want to capture # all files ending in .dbf: export ARCHIVEFILESPEC='*.dbf' export REMOTEHOST=server-01 export REMOTEDIRECTORY=/home/logtran/logfiles export TIMESTAMPFILE=${DIRECTORY}/.TIMESTAMP # The Cipher for Secure Shell to use: export CIPHER=blowfish-cbc #Commands: Change these paths as per your Operating System export FIND=/usr/bin/find export SCP=/usr/bin/scp export SSH=/usr/bin/ssh export LS=/bin/ls export TOUCH=/bin/touch export HOSTNAME=/usr/bin/hostname export FUSER=/sbin/fuser export TRUE=/bin/true export false=/bin/false function CheckSSH { # Check that we can reach the remotehost and execute a command $SSH $REMOTEHOST $HOSTNAME > /dev/null 2>&1 RETCODE=$? if [ $RETCODE -eq 0 ]; then $TRUE else $FALSE fi } function TimeStamp { # This is the heart of what this script does: # If there isn't a $TIMESTAMP file already then create one with # date at the unix epoch. The $TIMESTAMP file is used as a # placemarker, when a file, 'logfile.dbf' is successfully transferred, the timestamp # file is updated with the timestamp of 'logfile.dbf' # if [[ ! -f $TIMESTAMPFILE ]]; then $TOUCH -t 197001010000 $TIMESTAMPFILE || { print -u2 "ERROR: Cannot create $TIMESTAMPFILE" exit 1 } fi } function CreateArchiveList { # Uses the find command to generate a list of files newer than the timestamp file # i.e., ones that need to be processed and in this case delivered to the remote host. if [ -d $DIRECTORY ] ; then $FIND $DIRECTORY/ -name $ARCHIVEFILESPEC -newer $TIMESTAMPFILE 2>/dev/null else print -u2 "ERROR $?: cannot find $DIRECTORY" exit 1 fi } function ExcludeOpenFiles { # We don't want to send a file which is currently open, because it will be incomplete. while read FILENAME do if [[ -n "$($FUSER $FILENAME 2>/dev/null)" ]] ; then print -u2 "WARNING: file $FILENAME is in use skipping" # We don't need an alert for skipped files else print $FILENAME fi done } function ProcessArchiveList { while read FILENAME do $SCP -B -p -c $CIPHER $FILENAME $REMOTEHOST:$REMOTEDIRECTORY RETCODE=$? if [ $RETCODE -eq 0 ]; then print -u1 $FILENAME transferred successfully # now update the $TIMESTAMP placeholder to make CreateArchiveList # pick up only newer files than this on the next run: $TOUCH -r $FILENAME $TIMESTAMPFILE else print -u2 ERROR ${RETCODE}: $FILENAME failed to transfer fi done } # Shell Logic: Call the functions # First check if SSH can connect to the remote system: CheckSSH if [ $? -eq 0 ]; then TimeStamp CreateArchiveList | ExcludeOpenFiles | ProcessArchiveList else print -u2 "Could not establish SSH connection with $REMOTEHOST" fi