Я создал скрипт резервного копирования MySQL, который работает очень хорошо.
Проблемы возникают только с паролями, содержащими специальные символы, например:
xgT{uic[Is?uJ+
.
Вот важная часть сценария:
#!/bin/sh
FILE=mysql-$db.$DATE.sql.gz
ssh $SUSER@$SHOST "mysqldump -q -u $MUSER -h $MHOST -p$MPASS $db --no-create-db | gzip -9 > $FILE" 2> $ERROR
Я изменил это на:
ssh $SUSER@$SHOST 'mysqldump -q -u $MUSER -h $MHOST -p'\''$MPASS'\'' $db --no-create-db | gzip -9 > $FILE' 2> $ERROR
Как видите, я уже пробовал двойные кавычки. Но теперь получаю ошибку:
bash: $FILE: ambiguous redirect
Я получаю пароль и другую информацию из внешнего файла:
DB_HOST=000.000.000.000
DB_DATABASE=dbdame
DB_USER=db user
DB_PASS="xgT{uic[Is?uJ+"
В моем скрипте информация берется из внешнего файла:
Source dbserver.conf
MUSER=$DB_USER
MPASS=$DB_PASS
MHOST=$DB_HOST
DBS=$DB_DATABASE
решение1
Ваш пароль должен иметь экранированные специальные символы. Так что если ваш оригинальный пароль xgT{uic[Is?uJ+
будет xgT\{uic\[Is\?uJ\+
(Косая черта перед специальными символами).
Вы также можете посмотреть что-то уже написанное для этого, напримерAutoMySQLBackup, но я не уверен, нужна ли вам ежедневная, еженедельная или ежемесячная ротация резервных копий. Однако применяется то же правило: если в пароле есть специальные символы, эти специальные символы необходимо экранировать.
Надеюсь, это поможет!
решение2
Да. Это помогло избежать специальных символов:
MPASS=$(printf "%q\n" "$DB_PASS")
Но проблема с mysqldump все еще была. Я наконец выяснил, что mysqldump работал у меня только с паролями со специальными символами, когда я не указывал mysqldump хост (-h hostname). Похоже, это ошибка. Или нет?
К сожалению, у меня также есть сайты, где сервер mysql находится на другом хосте. Так что это решение не идеально.
решение3
Писать следует так:
ssh "$SUSER@$SHOST" "mysqldump -q -u \"$MUSER\" -h \"$MHOST\" -p\"$MPASS\" \"$db\" --no-create-db | gzip -9 > \"$FILE\"" 2> "$ERROR"
То есть, все переменные, используемые в качестве аргументов командной строки, должны быть защищены путем заключения в кавычки. Двойные кавычки вокруг переменных гарантируют, что выражение рассматривается как одно значение, поэтому оболочка не будет разбивать его на слова. Обратите внимание, что "
встроенные внутри "..."
нужно экранировать и записывать как \"
. Более простое решение — использовать одинарные кавычки вместо встроенных двойных, например:
ssh "$SUSER@$SHOST" "mysqldump -q -u '$MUSER' -h '$MHOST' -p'$MPASS' '$db' --no-create-db | gzip -9 > '$FILE'" 2> "$ERROR"
Наконец, мне интересно, действительно ли вы имели в виду 2> "$ERROR"
на локальном хосте, а не на удаленном хосте. Я подозреваю, что вы на самом деле хотели это на удаленном хосте, так что это еще одна ошибка в исходной командной строке. Если это так, то вот исправление:
ssh "$SUSER@$SHOST" "mysqldump -q -u '$MUSER' -h '$MHOST' -p'$MPASS' '$db' --no-create-db | gzip -9 > '$FILE' 2> '$ERROR'"