Щоб "автоматизувати" процес імпорту згенерованого .sql
файлу, уникаючи при цьому всіх пасток, які можна приховати при спробі передачі файлів, stdin
і stdout
просто скажіть MySQL виконати створений .sql
файл за допомогою SOURCE
команди в MySQL.
Синтаксис у короткій, але чудовій відповіді від Kshitij Sood дає найкращу вихідну точку. Якщо коротко, змініть команду OP відповідно до синтаксису Кшитія Соода та замініть команди на SOURCE
команду:
#!/bin/bash
mysql -u$user -p$password $dbname -Bse "SOURCE ds_fbids.sql
SOURCE ds_fbidx.sql"
Якщо ім'я бази даних включено в створений .sql
файл, його можна скинути з команди.
Тут існує презумпція, що створений файл дійсний як .sql
файл самостійно. Якщо файл не переспрямований, прокладений або яким-небудь іншим чином обробляється оболонкою, не виникає жодних проблем з необхідністю уникнути будь-якого з символів у створеному виході через оболонку. Звичайно, правила щодо того, що потрібно уникнути у .sql
файлі, все ж діють.
Як вирішувати проблеми безпеки навколо пароля в командному рядку або у my.cnf
файлі тощо, було добре розглянуто в інших відповідях, з відмінними пропозиціями. Моя улюблена відповідь від Danny розповідає про це, включаючи те, як впоратися з проблемою під час 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
файл, як це робив ОП, і SOURCE
цей файл, використовуючи простий синтаксис команди вгорі. Мови сценаріїв набагато кращі при обробці рядків, ніж оболонка, і більшість мають вбудовані процедури для обробки котирувань та уникнення, необхідних під час роботи з MySQL.