Solved [SOLVED] capturing errors in $var & nested variables empty

Here is my script.
Code:
[root@zap]/root/bin-> cat ./backup
#!/usr/local/bin/bash

user=XXXXXXXX   #Mysql Username
pass=XXXXXXXX   #Mysql Password
bd=/root/test   #Backup Directory

# Database Names to back up
declare -a dbs=(mysql connect_db)
date=`date +%m-%d-%y`
time=`date '+TIME: %H:%M:%S'`
ld=$bd/log
lf=$ld/backup.log_$date
num=${#dbs[@]}

######################## Begin Script #########################

# Create Backup Dir and chmod if not there
if [ ! -d $bd ]; then
        mkdir $bd $ld
        chmod -R 700 $bd
        echo "--- File created $date $time ---" >>$lf
fi

# Write Header to the logfile

echo "===================================================" >>$lf
echo "MYSQL DATABASE BACKUP STARTED AT $date $time" >>$lf

function dump {
        mysqldump -u$user -p$pass --default-character-set=utf8 \
                ${dbs[$i]} > $bd/${dbs[$i]}_$date
}

for ((i=0 ; i < $num ; i++)); do
        [color="Red"]er_arr[$i]=$(dump)[/color]
        echo ${er_arr[$i]}
        gzip -fq $bd/${dbs[$i]}_$date
        if [ er_arr[$i] != "" ]; then
            echo "DB:${dbs[$i]} failed with error(s): [color="red"]${er_arr[$i]}"[/color]
        fi
done

# Write Footer to dump cycle
echo "MYSQL DATABASE BACKUP COMPLETED AT $date $time" >>$lf

exit

I have two problems. I have been reading all day and cannot find the answers. I turn to FreeBSD.org with hat in hand.

The two highlighted snippets of code are wrong, and for the life of me I cannot figure out why.

When I execute my script, I get this:
Code:
[root@zap]/root/bin-> ./backup
mysqldump: Got error: 1033: Table './mysql/general_log' was created with a different version of MySQL and cannot be read when using LOCK TABLES

DB:mysql failed with error(s):

DB:connect_db failed with error(s):
[root@zap]/root/bin->

The mysqldump error doesn't store in the variable. I know this because when I comment the echo line out, it still show on &1:
Code:
for ((i=0 ; i < $num ; i++)); do
        er_arr[$i]=$(dump)
#       echo ${er_arr[$i]}
        gzip -fq $bd/${dbs[$i]}_$date
        if [ er_arr[$i] != "" ]; then
                echo "DB:${dbs[$i]} failed with error(s): ${er_arr[$i]}"
"backup" 48 lines, 1083 characters
[root@zap]/root/bin-> ./backup
mysqldump: Got error: 1033: Table './mysql/general_log' was created with a different version of MySQL and cannot be read when using LOCK TABLES
DB:mysql failed with error(s):
DB:connect_db failed with error(s):
[root@zap]/root/bin->

I have tried every combination of output redirect I can think of, as well as could find examples for and cannot get what I want. I want all output (&>) to go into the variable for reporting.

Problem #2:

For some reason, the echo nested in the if statement will expand the ${dbs[$i]} but not the ${er_arr[$i]}

Any help would be greatly appreciated. Redirects to useful reading appreciated as well, if not more. I have been using Unix now for a few month, and I must say I love it but with caveats. If you need glasses but don't have any, get some before you try your hand at Unix.
 
Test the return code of mysqldump. You can do that by testing the special variable $?:

Code:
mysqldump -u$user -p$pass --default-character-set=utf8 \
                ${dbs[$i]} > $bd/${dbs[$i]}_$date
if [ $? != 0 ]; then
   echo "Error!"
   exit
fi
 
This is a short example that shows how to get out the stdout from a function and get it back into a variable (either single or array assignement).

Hope this helps.

Code:
declare -a err_arr

function foo() {
    echo "Error $1 !" 1>&2
} 


for ((i=0 ; i < 10 ; i++)); do
    current_error=$( { foo "$i"; } 2>&1 )
    err_arr[$i]=$current_error
    echo "Error variable is  [$current_error]"
done

for ((i=0 ; i < 10 ; i++)); do
    echo "Error from array is " ${err_arr[i]}
done
 
Ok. After some pruning and testing, the final script looks like this:
Code:
[root@zap]/root/bin-> cat db_backup.sh
#!/usr/local/bin/bash


user=########                           #Mysql Username
pass=########                           #Mysql Password
bd=/var/backups                         #Backup Directroy
declare -a dbs=(mysql connect_db)       # Databases to be backed up

declare -a er_arr
date=`date +%m-%d-%y`
time=`date '+TIME: %H:%M:%S'`
ld=$bd/log
lf=$ld/backup.log_$date
num=${#dbs[@]}

######################## Begin Script #########################

# Create Backup Dir and chmod if not there
if [ ! -d $bd ]; then
        mkdir $bd $ld
        chmod -R 700 $bd
        echo "--- File created $date $time ---" >>$lf
fi

# Write Header to the logfile

echo "================================================================================" >>$lf
echo "     MYSQL DATABASE BACKUP STARTED AT $date $time" >>$lf
echo "================================================================================" >>$lf

function dump {
        mysqldump -u$user -p$pass --default-character-set=utf8 \
                ${dbs[$i]} > $bd/${dbs[$i]}_$date
}


for ((i=0 ; i < $num ; i++)); do
        current_error=$( ( dump ) 2>&1 )
        gzip -fq $bd/${dbs[$i]}_$date
        if [ -n "$current_error" ]; then
                echo "DB:${dbs[$i]} failed with error(s): $current_error" >>$lf
        fi
done

# Write Footer to dump cycle
echo " ----------> MYSQL DATABASE BACKUP COMPLETED AT $date $time" >>$lf

exit
[root@zap]/root/bin->

when installed on the machine it was instended for (proper version of mysql), it runs like a charm. But, as you probably noticed I was unable to use an array to capture the errors in an array. Well, more specifically I was unable to reference the array from within the if statement for some reason. Any ideas why?

Props and thanks to both of you for useful and quick responses. I hope someday I too can be as useful around this site.
 
fullauto said:
Well, more specifically I was unable to reference the array from within the if statement for some reason. Any ideas why?

I suspect the shell gets confused about the usage of [] for both doing a test and referencing an array cell. Using the explicit test does not solve the problem, so I suspect the only way is to use a temporary simple variable.
 
I suspect you are right... either way, it works. thanks for the help.
I'm just getting into this and this is the first attempt ever at any sort of scripting or programming. So, Im happy to just have ot work. I'm sure my scripts will get better. I have ALOT of them to right.x(
 
Well, if you want to do more complex script I suggest you to use a language like Perl. I was used to bash but I have to admit that sometimes it has too many complex features and requires a lot more debugging than a scripting language like Perl. Today I almost do all my scripting using Bourne Shell and Perl.
 
Back
Top