Щоб "автоматизувати" процес імпорту згенерованого .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.