Pour "automatiser" le processus d'importation du .sql
fichier généré , tout en évitant tous les pièges qui peuvent être cachés en essayant de faire passer des fichiers stdin
et stdout
, dites simplement à MySQL d'exécuter le .sql
fichier généré en utilisant la SOURCE
commande dans MySQL.
La syntaxe de la réponse courte, mais excellente, de Kshitij Sood , constitue le meilleur point de départ. En bref, modifiez la commande de l'OP selon la syntaxe de Kshitij Sood et remplacez les commandes en cela par la SOURCE
commande:
#!/bin/bash
mysql -u$user -p$password $dbname -Bse "SOURCE ds_fbids.sql
SOURCE ds_fbidx.sql"
Si le nom de la base de données est inclus dans le .sql
fichier généré , il peut être supprimé de la commande.
La présomption ici est que le fichier généré est valide en tant que .sql
fichier seul. En ne faisant pas que le fichier soit redirigé, redirigé ou de toute autre manière géré par le shell, il n'y a aucun problème avec le besoin d'échapper à l'un des caractères de la sortie générée à cause du shell. Les règles relatives à ce qui doit être échappé dans un .sql
fichier, bien sûr, s'appliquent toujours.
Comment traiter les problèmes de sécurité autour du mot de passe sur la ligne de commande, ou dans un my.cnf
fichier, etc., a été bien abordé dans d'autres réponses, avec d'excellentes suggestions. Ma réponse préférée , de Danny , couvre cela, y compris la façon de gérer le problème lors du cron
travail ou de toute autre chose.
Pour répondre à un commentaire (question?) Sur la réponse courte que j'ai mentionnée: Non, elle ne peut pas être utilisée avec une syntaxe HEREDOC, car cette commande shell est donnée. HEREDOC peut être utilisé dans la syntaxe de la version de redirection , (sans l' -Bse
option), car la redirection d'E / S est ce sur quoi HEREDOC est construit. Si vous avez besoin de la fonctionnalité de HEREDOC, il serait préférable de l'utiliser dans la création d'un .sql
fichier, même s'il s'agit d'un fichier temporaire, et d'utiliser ce fichier comme "commande" à exécuter avec la ligne de commandes 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
Gardez à l'esprit qu'en raison de l'expansion du shell, vous pouvez utiliser des variables de shell et d'environnement dans HEREDOC. L' inconvénient est que vous devez échapper à chaque backtick. MySQL les utilise comme délimiteurs pour les identificateurs mais le shell, qui obtient la chaîne en premier, les utilise comme délimiteurs de commandes exécutables. Manquez l'évasion sur un seul backtick des commandes MySQL, et le tout explose avec des erreurs. L'ensemble du problème peut être résolu en utilisant une LimitString citée pour le 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
La suppression de l'extension du shell de cette façon élimine le besoin d'échapper aux backticks et aux autres caractères spéciaux du shell. Il supprime également la possibilité d'utiliser des variables de shell et d'environnement en son sein. Cela supprime à peu près les avantages de l'utilisation d'un HEREDOC dans le script shell pour commencer.
L'autre option consiste à utiliser les chaînes entre guillemets multilignes autorisées dans Bash avec la version de la syntaxe du lot (avec le -Bse
). Je ne connais pas d'autres coques, donc je ne peux pas dire si elles y fonctionnent également. Vous devrez de toute façon l'utiliser pour exécuter plus d'un .sql
fichier avec la SOURCE
commande, car cela n'est pas terminé par un ;
comme le sont les autres commandes MySQL, et un seul est autorisé par ligne. La chaîne multiligne peut être entre guillemets simples ou doubles, avec les effets normaux sur l'expansion du shell. Il comporte également les mêmes mises en garde que l'utilisation de la syntaxe HEREDOC pour les backticks, etc.
Une solution potentiellement meilleure serait d'utiliser un langage de script, Perl, Python, etc., pour créer le .sql
fichier, comme l'a fait l'OP, et SOURCE
ce fichier en utilisant la syntaxe de commande simple en haut. Les langages de script sont bien meilleurs pour la manipulation de chaînes que le shell, et la plupart ont des procédures intégrées pour gérer les guillemets et les échappements nécessaires lors de l'utilisation de MySQL.