Still trying to get the basics down and I would like a different solution to what I'm currently doing and a better understanding of why it's happening. I've written a simple backup script that tars individual directories and then dumps them to a NFS drive. STDERR is being dumped into a process which echos a date stamp, and then the error to a tmp file (/tmp/backerrors.log). At the end of the script you will see I am mailing the tmp file if it has any data in it, after which I call for it to remove the file. Now here is where I get confused. Before the mail command is finished, the file is getting removed and cutting off bits of the message body.
If you run something like this, you will see what I mean (for me, the last line is being removed before the mail command is finished):
#!/bin/bash
#
#Want to enable error log emails?
EMAILLOGS="true"
EMAILTO="me@domain.com"
SUBJECT="Test Script"
#Where to dump errors if EMAILLOGS is false
ERRORLOG="/var/log/backuplog"
##Where are we sending stderr..
if [ $EMAILLOGS != "false" ]; then
exec 2> >(while read line; do echo -e "$(date):${line}\n"; done >>/tmp/errorlog)
else
exec 2>>$ERRORLOG
fi
echo -e "**error**\n**error**\n**error**" >&2
sleep 1
echo "piping to the error log for timestamp testing, one second" >&2
sleep 2
echo "two seconds" >&2
#Mail the errorlog if /tmp/backerrors.log exists and is > 0
if [ -s /tmp/errorlog ]; then
/usr/bin/mail -s "$SUBJECT" "$EMAILTO" < /tmp/errorlog
else
rm -f /tmp/errorlog
fi
rm -f /tmp/errorlog
Here is my script, at the end of which I've given it a 5 second sleep to complete the mail command. This can't be the correct way of doing, I assume..
#Want to enable error log emails?
EMAILLOGS="true"
EMAILTO="me@domain.com"
SUBJECT="Backup Error Log"
#Where to dump errors if EMAILLOGS is false
ERRORLOG="/var/log/backup/error.log"
#Set some main variables
set $(date)
MOUNTLOC="/mnt/bak"
##What is the root we are reading directories from?
DATA="/mail"
##Which directories do you want to exclude?
EXCLUDE="oldusers"
##What is the root we are writing to?
BACK=$MOUNTLOC
##Mount the NFS I'm backing to
mount $MOUNTLOC
##Variables to check if files exist
WEEKLYFILES=$(ls $BACK/weeklybak/*.tgz 2>/dev/null | wc -l)
INCREMFILES=$(ls $BACK/data_diff/*.tgz 2>/dev/null | wc -l)
##Where are we sending stderr..
if [ $EMAILLOGS == "true" ]; then
##This is process substitution: Read in sterr lines,
##echo back timstamp: error, then dump into a tmp file for mailing
exec 2> >(while read line; do echo -e "$(date):${line}\n"; done >/tmp/backerrors.log)
else
exec 2>>$ERRORLOG
fi
##Script start
TIMESTART=$(date +%Y\/%m\/%d-%H:%M)
printf "*--------------------$TIMESTART--------------------*\n"
if [ "$1" = "Sun" ] || [ "$WEEKLYFILES" = "0" ]; then
#If it's Sunday, or a full backup doesn't exist, remove incremented files and logs
if [ "$INCREMFILES" != "0" ]; then
echo "Purging old incremental files..."
rm -fv $BACK/data_diff/*.tgz
rm -fv $BACK/snars/*.snar
fi
#Just in case something is left over
echo "Purging old full backups..."
rm -fv $BACK/weeklybak/*.tgz
printf "Running full backup...\n"
cd $DATA
for DIRECTORY in $(ls -d *); do
tar \
--create --gzip \
--file=$BACK/weeklybak/${DIRECTORY}_$6-$2-$3.tgz \
--listed-incremental=$BACK/snars/${DIRECTORY}_backup.snar \
--exclude="$EXCLUDE" \
$DIRECTORY
done
cd ~
else
printf "Running incremental backup of emails...\n"
cd $DATA
for DIRECTORY in $(ls $DATA); do
tar \
--create --gzip \
--file=$BACK/data_diff/${DIRECTORY}_$6-$2-$3.tgz \
--listed-incremental=$BACK/snars/${DIRECTORY}_backup.snar \
--exclude="$EXCLUDE" \
$DIRECTORY
done
cd ~
fi
#Grab my scripts and cronjobs
printf "Grabbing cronjobs and scripts...\n"
tar \
--create --gzip \
--file=$BACK/rootscripts.tgz \
/root/scripts
tar \
--create --gzip \
--file=$BACK/crontabs.tgz \
/var/spool/cron/crontabs
#Mail the errorlog if /tmp/backerrors.log exists and is > 0
if [ -s /tmp/backerrors.log ]; then
/usr/bin/mail -s "$SUBJECT" "$EMAILTO" < /tmp/backerrors.log
else
rm -f /tmp/backerrors.log
fi
##Define time, now that we've finished
TIMEFINISHED=$(date +%Y\/%m\/%d-%H:%M)
##Log finished time
printf "Finished...\n"
printf "*--------------------$TIMEFINISHED--------------------*\n\n\n"
##Umount the NFS
umount $MOUNTLOC
#Give our mail command time to process, then remove the back up errors
sleep 5
rm -f /tmp/backerrors.log
exit