Как выполнить команду MySQL из сценария оболочки? - PullRequest
111 голосов
/ 08 ноября 2011

Как выполнить команду SQL с помощью сценария оболочки, чтобы сделать ее автоматизированной?

Я хочу восстановить данные, собранные в файле SQL, с помощью сценария оболочки.Я хочу подключиться к серверу и восстановить данные.Команда работает, когда выполняется отдельно через командную строку SSH.

Я использую эту команду:

mysql -h "server-name" -u root "password" "database-name" < "filename.sql"

Это код сценария оболочки, который создает файл 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

Как правильно это сделать?

Ответы [ 14 ]

157 голосов
/ 08 ноября 2011

Вам необходимо использовать флаг -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 в пакетном режиме, подобные приведенным выше для командыстрока и в скриптах оболочки все время.Трудно диагностировать, что не так с вашим сценарием оболочки, потому что вы не указали точный сценарий или какие-либо сообщения об ошибках.Я предлагаю вам отредактировать исходный вопрос выше и привести примеры того, что идет не так.

Также, когда я устраняю неполадки в сценарии оболочки, я использую флаг -x, чтобы видеть, как он выполняет каждую команду:

$ bash -x myscript.sh
105 голосов
/ 30 октября 2012

Используйте этот синтаксис:

mysql -u $user -p$passsword -Bse "command1;command2;....;commandn"
36 голосов
/ 09 ноября 2011

Все предыдущие ответы великолепны.Если вы хотите выполнить простую однострочную команду sql, вы также можете использовать опцию -e.

mysql -h <host> -u<user> -p<password> database -e \
  "SELECT * FROM blah WHERE foo='bar';"
18 голосов
/ 11 декабря 2013

Как выполнить сценарий SQL, используйте следующий синтаксис:

mysql --host= localhost --user=root --password=xxxxxx  -e "source dbscript.sql"

Если вы используете хост в качестве локального хоста, вам не нужно упоминать его.Вы можете использовать это:

mysql --user=root --password=xxxxxx  -e "source dbscript.sql"

Это должно работать для Windows и Linux.

Если содержание пароля содержит ! (восклицательный знак), вы должны добавить \ (обратный слеш)) перед ним.

8 голосов
/ 09 июня 2015

На суть вопроса уже отвечали уже несколько раз, я просто подумал, что добавлю, что обратные знаки (s) имеют beaning как в скриптах оболочки, так и в SQL. Если вам нужно использовать их в SQL для указания имени таблицы или базы данных, вам нужно экранировать их в сценарии оболочки следующим образом:

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.

5 голосов
/ 13 марта 2013
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
5 голосов
/ 08 ноября 2011

Вы забыли -p или --password= (последний лучше читается):

mysql -h "$server_name" "--user=$user" "--password=$password" "--database=$database_name" < "filename.sql"

(Кавычки не нужны, если вы уверены, что ваши учетные данные / имена не содержат пробелов или специальных символов оболочки.)

Обратите внимание, что на странице руководства также указано, что предоставление учетных данных в командной строке небезопасно. Так что следуйте советам Билла о my.cnf.

4 голосов
/ 08 ноября 2011

Как указано выше, вы можете использовать -p для передачи пароля на сервер.

Но я рекомендую это:

mysql -h "hostaddress" -u "username" -p "database-name" < "sqlfile.sql"

Обратите внимание, что пароля там нет.Затем вам будет предложено ввести пароль.Я бы тогда набрал его. Чтобы ваш пароль не вошел в историю командной строки сервера.

Это базовая мера безопасности.

Если безопасность не имеет значения, ябудет просто временно удалить пароль из базы данных пользователя.Затем после импорта - добавьте его заново.

Таким образом, любые другие учетные записи, которые могут иметь тот же пароль, не будут скомпрометированы.

Также кажется, что в вашем сценарии оболочки выне ждет / проверяет, существует ли файл, который вы пытаетесь импортировать, на самом деле.Возможно, сценарий Perl еще не закончен.

2 голосов
/ 20 января 2017

Важным соображением для доступа к mysql из сценария оболочки, используемого в cron, является то, что mysql просматривает вошедшего в систему пользователя, чтобы определить .my.cnf для загрузки.

Это не работает с cron.Это также может сбить с толку, если вы используете su / sudo, поскольку вошедший в систему пользователь может не быть тем пользователем, которым вы работаете.

Я использую что-то вроде:

mysql --defaults-extra-file=/path/to/specific/.my.cnf -e 'SELECT something FROM sometable'

Просто убедитесь, чточто владение и права пользователей и групп установлены соответствующим образом в файле .my.cnf.

1 голос
/ 18 июля 2018

Использование

echo "your sql script;" | mysql -u -p -h db_name
...