Para "automatizar" el proceso de importación del .sql
archivo generado , evitando al mismo tiempo todas las trampas que pueden ocultarse al intentar pasar los archivos stdin
y stdout
, simplemente dígale a MySQL que ejecute el .sql
archivo generado utilizando el SOURCE
comando en MySQL.
La sintaxis en la breve pero excelente respuesta , de Kshitij Sood , ofrece el mejor punto de partida. En resumen, modifique el comando del OP de acuerdo con la sintaxis de Kshitij Sood y reemplace los comandos con el SOURCE
comando:
#!/bin/bash
mysql -u$user -p$password $dbname -Bse "SOURCE ds_fbids.sql
SOURCE ds_fbidx.sql"
Si el nombre de la base de datos se incluye en el .sql
archivo generado , se puede quitar del comando.
La presunción aquí es que el archivo generado es válido como un .sql
archivo por sí solo. Al no tener el archivo redirigido, canalizado o de cualquier otra manera manejado por el shell, no hay problema con la necesidad de escapar de cualquiera de los caracteres en la salida generada debido al shell. Las reglas con respecto a lo que se debe escapar en un .sql
archivo, por supuesto, todavía se aplican.
La forma de abordar los problemas de seguridad relacionados con la contraseña en la línea de comandos, o en un my.cnf
archivo, etc., se ha abordado bien en otras respuestas, con algunas sugerencias excelentes. Mi respuesta favorita , de Danny , cubre eso, incluyendo cómo manejar el problema cuando se trata de cron
trabajos o cualquier otra cosa.
Para abordar un comentario (pregunta?) Sobre la respuesta corta que mencioné: No, no se puede usar con una sintaxis HEREDOC, ya que se da ese comando de shell. HEREDOC se puede usar en la sintaxis de la versión de redirección (sin la -Bse
opción), ya que la redirección de E / S es la base de HEREDOC. Si necesita la funcionalidad de HEREDOC, sería mejor usarlo en la creación de un .sql
archivo, incluso si es temporal, y usar ese archivo como el "comando" para ejecutar con la línea de lote 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
Tenga en cuenta que debido a la expansión de shell, puede usar variables de shell y de entorno dentro de HEREDOC. El inconveniente es que debes escapar de todos y cada uno de los backticks. MySQL los usa como delimitadores para identificadores, pero el shell, que obtiene la cadena primero, los usa como delimitadores de comandos ejecutables. Echa de menos el escape en un solo backtick de los comandos de MySQL, y todo explota con errores. Todo el problema se puede resolver utilizando un LimitString citado para el 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
Eliminar la expansión de shell de esa manera elimina la necesidad de escapar de los backticks y otros caracteres especiales de shell. También elimina la capacidad de usar shell y variables de entorno dentro de él. Para empezar, eso elimina los beneficios de usar un HEREDOC dentro del script de shell.
La otra opción es utilizar las cadenas entre comillas de varias líneas permitidas en Bash con la versión de sintaxis por lotes (con el -Bse
). No conozco otros proyectiles, así que no puedo decir si también funcionan allí. Debería usar esto para ejecutar más de un .sql
archivo con el SOURCE
comando de todos modos, ya que eso no está terminado por un ;
como otros comandos MySQL, y solo se permite uno por línea. La cadena de varias líneas puede ser entre comillas simples o dobles, con los efectos normales en la expansión de shell. También tiene las mismas advertencias que el uso de la sintaxis HEREDOC para backticks, etc.
Una solución potencialmente mejor sería usar un lenguaje de script, Perl, Python, etc., para crear el .sql
archivo, como lo hizo el OP, y SOURCE
ese archivo usando la sintaxis de comando simple en la parte superior. Los lenguajes de secuencias de comandos son mucho mejores en la manipulación de cadenas que el shell, y la mayoría tienen procedimientos integrados para manejar las citas y los escapes necesarios cuando se trata con MySQL.