Как выполнить команду 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.