bash mysql dump

Встала задача миграции сервера apache на новое железо и хочется автаматизировать процесс, чтобы не тыкать в терминале многабукав. Вот, настолько сильная лень что из-за нее практически готов выучить bash. Нашел в Интернете один замечательный скриптик:

#!/usr/local/bin/bash
# MySQL backup script

#ulimit -t 3600
#user name
USER="madmentat"
#user password
PASSWORD="Password666"
#MYSQL host address ("localhost" by default)
HOST="localhost"
#dirrectory for backups
DIR="/data/fileserver/share/mysqldump"

GZIP="$(which gzip)"
MYSQL="$(which mysql)"
MYSQLDUMP="$(which mysqldump)"
NOW=$(date +"%Y_%m_%d_%H-%M")

echo "Choose database number:"
i=1
for db in $($MYSQL -u$USER -h$HOST -p$PASSWORD -Bse 'show databases')
do
echo "$i -  $db"
DATABASES[$i]=$db
i=$((i+1))
done

read RESULT
if [ "$RESULT" -ge 1 ] && [ "$RESULT" -lt ${#DATABASES[@]} ]
then
eval "DB=${DATABASES[$RESULT]}"
eval "FILE=$DIR$DB-$NOW.sql.gz"
$MYSQLDUMP -u$USER -h$HOST -p$PASSWORD $DB | $GZIP -9 > $FILE
else
echo "Wrong number!"
fi

Запустил на своем сервачке и получил такое сообщение:

1 -  base
mysqldump.sh: 24: DATABASES[1]=base: not found
2 -  information_schema
mysqldump.sh: 24: DATABASES[2]=information_schema: not found
3 -  ncompservice
mysqldump.sh: 24: DATABASES[3]=ncompservice: not found

Так вот, интересно, какого хрена?! Ведь получается что переменная db получает название базы, а i свой числовой индекс... Я так полнимаю, что у меня таким образом

    DATABASES[$i]=$db

должен получаться массив, где i - количество баз, соответствующее ячейке в массиве, а db - их названия... Кстати, а вывод команды в круглых скобках ($MYSQL -u$USER -h$HOST -p$PASSWORD -Bse 'show databases') получается такой:

mysql -umadmentat -hlocalhost -pPassword666 -Bse 'show databases'
mysql: [Warning] Using a password on the command line interface can be insecure.
base
information_schema
ncompservice

Дополню тему и, получается, здесь меняется суть вопроса. Похоже, bash тупо не хочет работать с массивами. Пробовал разные простенькие варианты, например, создал скриптик array.sh со следующим содержимым

#!/bin/bash
array[0]=red
array[1]=green
array[2]=blue
echo ${array[2]}

Запускаю, получаю ответ:

array.sh: 2: array[0]=red: not found
array.sh: 3: array[1]=green: not found
array.sh: 4: array[2]=blue: not found
array.sh: 5: Bad substitution

Если переписать так

#!/bin/bash
array=(red green blue)
echo ${array[@]}

Ругается следующим образом:

array.sh: 2: Syntax error: "(" unexpected

Короче, вывод какой? А такой, что тупо не работают массивы в bash! Причем, испытано на 2 компах с разными архитектурами процессоров и разными операционными системами. Ну и отсюда вопрос: как это так?! Может, их надо как-то инициировать в конфигах?


Ответы (1 шт):

Автор решения: Andrey madmentat

Так, найдена причина некорректной работы bash с массивами. Во-первых, при объявлении следует соблюдать некоторую осторожность. Например, следующий способ некорректен:

my_array[1] = 34
my_array[2] = 57

Корректен такой:

my_array[1]=34
my_array[2]=57

То есть, не следует допускать лишних пробелов. Ну, и самое главное - это способ запуска скрипта!

sh array.sh

Не правильно! Правильно так:

./array.sh

Далее переписал код скрипта под свои нужды. Итоговый вариант получился такой:

#!/bin/bash
# MySQL backup script

#ulimit -t 3600
#user name
USER="madmentat"
#user password
PASSWORD="Password666"
#MYSQL host address ("localhost" by default)
HOST="localhost"
#dirrectory for backups
DIR="/home/madmentat/sources/dump"

GZIP="$(which gzip)"
MYSQL="$(which mysql)"
MYSQLDUMP="$(which mysqldump)"
NOW=$(date +"%Y_%m_%d_%H-%M")

echo "Choose database number:"
i=1
for db in $($MYSQL -u$USER -h$HOST -p$PASSWORD -Bse 'show databases')
do
DATABASES[$i]=$db
FILE[$i]=$DIR/${DATABASES[$i]}-$NOW.sql
echo "${FILE[$i]}"
mysqldump -u$USER -h$HOST -p$PASSWORD ${DATABASES[$i]} > ${FILE[$i]}
i=$((i+1))
done

echo "Dumps are  done! Look for your files in $DIR"
→ Ссылка