Как выполнить команду MySQL из оболочки script?
Как я могу выполнить команду SQL через оболочку script, чтобы я мог ее автоматизировать?
Я хочу восстановить данные, которые я собрал в файле SQL, используя оболочку script. Я хочу подключиться к серверу и восстановить данные. Команда работает, когда выполняется отдельно через командную строку SSH.
Это команда, которую я использую:
mysql -h "server-name" -u root "password" "database-name" < "filename.sql"
Это код оболочки script, который создает файл ds_fbids.sql
и передает его в mysql.
perl fb_apps_frm_fb.pl
perl fb_new_spider.pl ds_fbids.txt ds_fbids.sql
mysql -h dbservername -u username -ppassword dbname < ds_fbids.sql
Каков правильный способ сделать это?
Ответы
Ответ 1
Для отправки пароля вам необходимо использовать флаг -p
. И это сложно, потому что у вас не должно быть пробелов между -p
и паролем.
$ mysql -h "server-name" -u "root" "-pXXXXXXXX" "database-name" < "filename.sql"
Если вы используете пробел после -p
, он вызывает интерактивный запрос клиента mysql для пароля, а затем он интерпретирует следующий аргумент команды как имя базы данных:
$ mysql -h "server-name" -u "root" -p "XXXXXXXX" "database-name" < "filename.sql"
Enter password: <you type it in here>
ERROR 1049 (42000): Unknown database 'XXXXXXXX'
Собственно, я предпочитаю хранить пользователя и пароль в ~/.my.cnf, поэтому мне не нужно размещать его в командной строке:
[client]
user = root
password = XXXXXXXX
Тогда:
$ mysql -h "server-name" "database-name" < "filename.sql"
Ваш комментарий:
Я запускаю командные команды mysql в пакетном режиме, как указано выше, в командной строке и в сценариях оболочки все время. Трудно диагностировать, что случилось с вашей оболочкой script, потому что вы не поделились точным script или выходом любой ошибки. Я предлагаю вам отредактировать исходный вопрос выше и привести примеры того, что пойдет не так.
Также, когда я искажаю оболочку script, я использую флаг -x
, чтобы я мог видеть, как он выполняет каждую команду:
$ bash -x myscript.sh
Ответ 2
Используйте этот синтаксис:
mysql -u $user -p$passsword -Bse "command1;command2;....;commandn"
Ответ 3
Все предыдущие ответы велики. Если это простая, одна строка sql-команды, которую вы хотите запустить, вы также можете использовать опцию -e.
mysql -h <host> -u<user> -p<password> database -e \
"SELECT * FROM blah WHERE foo='bar';"
Ответ 4
Как выполнить SQL script, используйте этот синтаксис:
mysql --host= localhost --user=root --password=xxxxxx -e "source dbscript.sql"
Если вы используете хост как localhost, вам не нужно упоминать об этом. Вы можете использовать это:
mysql --user=root --password=xxxxxx -e "source dbscript.sql"
Это должно работать для Windows и Linux.
Если содержимое пароля содержит !
(восклицательный знак), вы должны добавить перед ним \
(обратная косая черта).
Ответ 5
Ядро вопроса уже ответило несколько раз, я просто подумал, что добавлю, что backticks (s) имеют beaning как в сценариях оболочки, так и в SQL. Если вам нужно использовать их в SQL для указания имени таблицы или базы данных, вам необходимо сбежать от нее в оболочке script так:
mysql -p=password -u "root" -Bse "CREATE DATABASE \`${1}_database\`;
CREATE USER '$1'@'%' IDENTIFIED BY '$2';
GRANT ALL PRIVILEGES ON `${1}_database`.* TO '$1'@'%' WITH GRANT OPTION;"
Конечно, генерация SQL через конкатенированный вход пользователя (переданные аргументы) не должна выполняться, если вы не доверяете пользовательскому вводу. Это было бы намного более безопасным, чтобы поместить его на другой язык сценариев с поддержкой параметров/правильной эвакуации строки для вставки в MySQL.
Ответ 6
Вы забыли -p
или --password=
(последний лучше читается):
mysql -h "$server_name" "--user=$user" "--password=$password" "--database=$database_name" < "filename.sql"
(Кавычки не нужны, если вы уверены, что ваши учетные данные/имена не содержат пробелов или специальных символов оболочки.)
Обратите внимание, что в manpage также указано, что предоставление учетных данных в командной строке небезопасно. Так что следуйте совету Билла о my.cnf.
Ответ 7
mysql -h "hostname" -u usr_name -pPASSWD "db_name" < sql_script_file
(при необходимости используйте полный путь для sql_script_file
)
Если вы хотите перенаправить вывод в файл
mysql -h "hostname" -u usr_name -pPASSWD "db_name" < sql_script_file > out_file
Ответ 8
Как указано выше, вы можете использовать -p для передачи пароля на сервер.
Но я рекомендую это:
mysql -h "hostaddress" -u "username" -p "database-name" < "sqlfile.sql"
Обратите внимание, что пароля нет. Затем он запросит пароль. Я бы THEN напечатал его. Таким образом, ваш пароль не войдет в историю командной строки серверов.
Это основная мера безопасности.
Если безопасность не вызывает беспокойства, я просто временно удалю пароль из пользователя базы данных. Затем после импорта заново добавьте его.
Таким образом, любые другие учетные записи, которые могут иметь один и тот же пароль, не будут скомпрометированы.
Также кажется, что в вашей оболочке script вы не ожидаете/проверяете, действительно ли файл, который вы пытаетесь импортировать, существует. Perl script еще не завершен.
Ответ 9
Важным соображением для доступа к mysql из оболочки script, используемой в cron, является то, что mysql просматривает зарегистрированного пользователя для определения загружаемого .my.cnf.
Это не работает с cron. Он также может запутаться, если вы используете su/sudo, поскольку зарегистрированный пользователь может не быть пользователем, которого вы используете как.
Я использую что-то вроде:
mysql --defaults-extra-file=/path/to/specific/.my.cnf -e 'SELECT something FROM sometable'
Просто убедитесь, что права пользователя и группы и разрешения установлены соответствующим образом и плотно в файле .my.cnf.
Ответ 10
mysql_config_editor set --login-path=storedPasswordKey --host=localhost --user=root --password
Как выполнить командную строку с защищенным паролем? используйте редактор конфигурации.
Как и в mysql 5.6.6, вы можете сохранить пароль в файле конфигурации, а затем выполнить команды cli, подобные этому....
mysql --login-path=storedPasswordKey ....
- логин-путь заменяет переменные... host, user AND password. отлично правы!
Ответ 11
#!/bin/sh
#Procedures = update
#Scheduled at : Every 00.05
v_path=/etc/database_jobs
v_cnt=0
MAILTO="[email protected] [email protected] [email protected]"
touch "$v_path/db_db_log.log"
#test
mysql -uusername -ppassword -h111.111.111.111 db_name -e "CALL functionName()" > $v_path/db_db_log.log 2>&1
if [ "$?" -eq 0 ]
then
v_cnt=`expr $v_cnt + 1`
mail -s "db Attendance Update has been run successfully" $MAILTO < $v_path/db_db_log.log
else
mail -s "Alert : db Attendance Update has been failed" $MAILTO < $v_path/db_db_log.log
exit
fi
Ответ 12
использование
echo "your sql script;" | mysql -u -p -h db_name
Ответ 13
Чтобы "автоматизировать" процесс импорта сгенерированного файла .sql
, избегая при этом всех ловушек, которые могут быть скрыты при попытке передать файлы через stdin
и stdout
, просто скажите MySQL выполнить сгенерированный файл .sql
с помощью команды SOURCE
в MySQL.
Синтаксис в коротком, но превосходном ответе Кшития Суда дает лучшую отправную точку. Короче говоря, измените команду OP в соответствии с синтаксисом Kshitij Sood и замените команды в ней командой SOURCE
:
#!/bin/bash
mysql -u$user -p$password $dbname -Bse "SOURCE ds_fbids.sql
SOURCE ds_fbidx.sql"
Если имя базы данных включено в сгенерированный файл .sql
, его можно удалить из команды.
Предполагается, что сгенерированный файл сам по себе действителен как файл .sql
. Поскольку файл не перенаправляется, не передается по конвейеру или иным образом не обрабатывается оболочкой, нет проблемы с необходимостью экранирования каких-либо символов в сгенерированном выводе из-за оболочки. Правила относительно того, что должно быть экранировано в файле .sql
, конечно, все еще применяются.
Как решать проблемы безопасности, связанные с паролем в командной строке, в файле my.cnf
и т.д., Было подробно рассмотрено в других ответах с некоторыми отличными предложениями. Мой любимый ответ от Дэнни охватывает это, в том числе, как справиться с проблемой при работе с cron
, или что-то еще.
Чтобы ответить на комментарий (вопрос?) К короткому ответу, который я упомянул: нет, его нельзя использовать с синтаксисом HEREDOC, поскольку дается эта команда оболочки. HEREDOC может использоваться в синтаксисе версии перенаправления (без опции -Bse
), поскольку перенаправление ввода/вывода - это то, что построено вокруг HEREDOC. Если вам нужна функциональность HEREDOC, было бы лучше использовать ее при создании файла .sql
, даже если он временный, и использовать этот файл в качестве "команды" для выполнения с помощью пакетной строки MySQL.
#!/bin/bash
cat >temp.sql <<SQL_STATEMENTS
...
SELECT \'column_name\' FROM \'table_name\' WHERE \'column_name\'='$shell_variable';
...
SQL_STATEMENTS
mysql -u $user -p$password $db_name -Be "SOURCE temp.sql"
rm -f temp.sql
Помните, что из-за расширения оболочки вы можете использовать переменные оболочки и среды в HEREDOC. Недостатком является то, что вы должны избегать каждого обратного удара. MySQL использует их в качестве разделителей для идентификаторов, но оболочка, которая получает строку первой, использует их в качестве разделителей исполняемых команд. Пропустите выход из-за единственного обратного удара команд MySQL, и все это взорвется с ошибками. Вся проблема может быть решена с помощью цитируемой LimitString для HEREDOC:
#!/bin/bash
cat >temp.sql <<'SQL_STATEMENTS'
...
SELECT 'column_name' FROM 'table_name' WHERE 'column_name'='constant_value';
...
SQL_STATEMENTS
mysql -u $user -p$password $db_name -Be "SOURCE temp.sql"
rm -f temp.sql
Удаление расширения оболочки таким способом избавляет от необходимости избегать обратных символов и других специальных символов оболочки. Это также устраняет возможность использования переменных оболочки и среды внутри него. Это в значительной степени устраняет преимущества использования HEREDOC внутри сценария оболочки.
Другой вариант - использовать многострочные строки в кавычках, разрешенные в Bash, с версией синтаксиса пакета (с -Bse
). Я не знаю других оболочек, поэтому не могу сказать, работают ли они там тоже. В любом случае вам нужно будет использовать это для выполнения более одного файла .sql
с командой SOURCE
, так как это не завершается символом ;
как и другие команды MySQL, и только одна разрешена для каждой строки. Многострочная строка может быть в одинарных или двойных кавычках, что обычно влияет на расширение оболочки. Он также имеет те же предостережения, что и использование синтаксиса HEREDOC для обратных галочек и т.д.
Потенциально лучшим решением было бы использование языка сценариев Perl, Python и т.д. Для создания файла .sql
, как это делал OP, и SOURCE
этого файла с использованием простого командного синтаксиса вверху. Языки сценариев гораздо лучше работают со строками, чем оболочка, и большинство из них имеют встроенные процедуры для обработки цитирования и экранирования, необходимые при работе с MySQL.