У меня есть следующий код как часть сценария, целью которого является дублирование локального веб-сайта (в моей среде xenial-сервера Ubuntu 16.04). Имя дублированного имени сайта, имя пользователя БД и имя экземпляра базы данных одинаковы и представлены в переменной ${domain}
, а ${rps}
содержит пароль root Mysql, а $ {sps} содержит дублированного пользователя базы данных сайта пароль.
Первая часть кода работает нормально (echo
и read
). Вторая часть не работает (echo
- |
в оболочку Mysql):
echo "1/3: Please enter the domain of the site for duplication." && read domain
echo "2/3: Please enter the password for your Mysql root user." && read -s rps
echo "3/3: Please enter the password of the site DB user." && read -s sps
echo "DROP USER IF EXISTS 'test'@'localhost';" | mysql -u root -p"${rps}
echo "DROP database IF EXISTS test;" | mysql -u root -p"${rps}
echo "CREATE USER 'test'@'localhost' IDENTIFIED BY \"${sps}\";" | mysql -u root -p"${rps}
echo "CREATE database test;" | mysql -u root -p"${rps}
echo "GRANT ALL PRIVILEGES ON test.* TO test@localhost;" | mysql -u root -p"${rps}
Это сделано для обеспечения переменной подстановки переменной ${sps
} (замена переменных не может произойти внутри оболочки mysql, поэтому ее необходимо выполнить за пределами и отправить в оболочку mysql
).
Все операции с эхо-сигналом терпят неудачу, они запускают вторичное приглашение.
Почему операции эхо-канала терпят неудачу, может быть, это проблема с регулярным выражением?
Полный код доступен здесь.
Я также голосую, чтобы закрыть этот вопрос, но, поскольку у меня было время, я подумал, что напишу дополнительную информацию, которая может помочь.
В ваших образцах кода сделано несколько небольших ошибок.
Не рекомендуется передавать пароль в терминале, так как все пользователи в системе могут видеть операцию и пароль. Например, с простым запросом на ps auxwww
.
Лучшим вариантом является использование mysql_config_editor
для создания безопасного входа в систему, который не требует пароля при использовании с localhost. Затем вы можете использовать что-то вроде mysql --login-path=master
и пароль не нужен.
Если вы действительно хотите опустить пароли, показанные в обычном текстовом пути, вы должны действительно использовать длинный синтаксис, который есть:
mysql --password=plaintext --user=user --database=dbname < "mysql query"
Или же
echo "mysql query" | mysql --password=plaintext --user=user --database=dbname
Или же
mysql --password=plaintext --user=user --database=dbname << END
mysql query to run;
another mysql query to run;
and another mysql query to run;
END
Или, возможно, лучший взгляд на ваш код:
mysql --password=plaintext --user=user --database=dbname --execute='mysql query'
Но вы должны получить предупреждение (которое я не могу вспомнить сейчас, что говорит) о том, что пароль находится на виду или что-то в этом роде.
Чтобы использовать один из ваших образцов кода, строка сценария будет (не требуется echo
):
mysql --user=root --password=${rps} --execute="DROP USER IF EXISTS 'test'@'localhost';"
Теперь, почему вы скомпилировали код (как вы теперь знаете).
Проблема заключается в "
до ${rps}
. Удаление этого "
будет работать ", но я бы вообще не использовал этот код, поскольку он имеет другие потенциальные проблемы.
Например, введите следующий пароль пользователя root
когда ваш скрипт запросит пароль:
password; -e 'DROP ALL DATABASES'
Это приведет к удалению всех баз данных (если я правильно понял синтаксис).