Я должен начать этот пост, сказав, что я не рекомендую этот метод для всех ситуаций из-за потенциальных проблем безопасности, а также некоторых компромиссов читаемости. Если это вас не пугает, продолжайте читать.
Недавно я столкнулся с ситуацией, когда мне нужно было обновить скрипт-клон MySQL, написанный на bash, для извлечения данных с нескольких серверов MySQL и записи на один сервер. Мы часто делаем это для быстрого копирования данных из одной среды в другую для тестирования. Оригинальный сценарий был написан с предположением об одном исходном сервере и выглядел примерно так:
source_mysql_host="not.the.best.idea" source_mysql_user="xxx" source_mysql_passwd="yyy" echo ; echo " ==> Cloning databases. Source: $source_mysql_host, Destination: $dest_mysql_host" DATABASES=`mysql -u${source_mysql_user} "-p${source_mysql_passwd}" -h${source_mysql_host} \ -NBe 'show databases' | egrep -v '^information_schema|performance_schema|mysql|test|backups$'` for db in $DATABASES; do echo " ==> Cloning database '$db' .. " $mysqldump_cmd -u${source_mysql_user} "-p${source_mysql_passwd}" -h${source_mysql_host} --add-drop-database --database ${db} | \ mysql -u${dest_mysql_user} "-p${dest_mysql_passwd}" -h${dest_mysql_host} done
(Полный блок кода состоял из 26 строк. Многое было пропущено, так как не относится к этой статье)
Чтобы обновить этот скрипт для клонирования данных с нескольких серверов, мы могли бы просто продублировать весь блок кода из 26 строк и изменить переменные так, чтобы первый блок использовал $ OLAP_mysql_host, а другой — $ OLTP_mysql_host и т. Д., Но это не быть очень DRY .
В итоге я обернул блок кода в новый цикл for и использовал косвенные ссылки bash для переключения между исходными серверами MySQL. Обратите внимание на уродливые косвенные ссылки bash. Это работает, и мы остаемся сухими. Стоило ли это? Может быть, может и нет. знак равно
OLTP_source_mysql_host="not.the.best.idea" OLTP_source_mysql_user="xxx" OLTP_source_mysql_passwd="yyy" OLAP_source_mysql_host="not.the.best.idea.2" OLAP_source_mysql_user="xxx" OLAP_source_mysql_passwd="yyy" for type in "OLTP" "OLAP"; do # use bash's indirect references. very ugly, but helps us stay DRY _mysql_source_host=$(eval "echo \$$(echo ${type}_source_mysql_host)") _mysql_source_user=$(eval "echo \$$(echo ${type}_source_mysql_user)") _mysql_source_passwd=$(eval "echo \$$(echo ${type}_source_mysql_passwd)") _schema_only_tables=$(eval "echo \$$(echo ${type}_SCHEMA_ONLY_TABLES)") echo ; echo " ==> Cloning ${type} databases. Source: $_mysql_source_host, Destination: $dest_mysql_host" # get a list of databases, excluding the mysql system db's (ie: mysql, test, ...) DATABASES=`mysql -u${_mysql_source_user} "-p${_mysql_source_passwd}" -h${_mysql_source_host} \ -NBe 'show databases' | egrep -v '^information_schema|performance_schema|mysql|test|backups$'` for db in $DATABASES; do echo " ==> Cloning database '$db' .. " $mysqldump_cmd -u${_mysql_source_user} "-p${_mysql_source_passwd}" -h${_mysql_source_host} --add-drop-database --database ${db} | \ mysql -u${dest_mysql_user} "-p${dest_mysql_passwd}" -h${dest_mysql_host} done done