Est-il possible à partir d'un script bash de vérifier si une base de données mysql existe? En fonction du résultat, effectuez une autre action ou terminez le script?
Exemple de script (Merci à Bill Karwin pour les commentaires --user
et --password
!):
#!/bin/bash
## --user=XXXXXX --password=XXXXXX *may* not be necessary if run as root or you have unsecured DBs but
## using them makes this script a lot more portable. Thanks @billkarwin
RESULT=`mysqlshow --user=XXXXXX --password=XXXXXX myDatabase| grep -v Wildcard | grep -o myDatabase`
if [ "$RESULT" == "myDatabase" ]; then
echo YES
fi
Voici à quoi ressemblent les commandes lorsqu'elles sont exécutées à l'invite:
[root@Host ~]# mysqlshow myDatabase
Wildcard: myDatabase
+------------------+
| Databases |
+------------------+
| myDatabase |
+------------------+
Si aucun DB n'existe, la sortie ressemblera à ceci:
[root@Host ~]# mysqlshow myDatabase
Wildcard: myDatabase
+-----------+
| Databases |
+-----------+
+-----------+
Ensuite, analysez la sortie et faites ce que vous devez faire en fonction de son existence ou non!
Je donne +1 à answer by @chown , mais voici une autre alternative: si le script bash s'exécute localement avec l'instance MySQL et que vous connaissez le chemin d'accès à datadir, vous pouvez tester:
if [ -d /var/lib/mysql/databasename ] ; then
# Do Stuff ...
fi
Cela suppose également que votre utilisateur Shell exécutant le script dispose de privilèges au niveau du système de fichiers pour lire le contenu du datadir MySQL. C'est souvent le cas, mais ce n'est pas certain.
mysqlshow "test" > /dev/null 2>&1 && echo "Database exists."
En fonction de l'état de sortie de la commande mysqlshow, il exécutera l'écho suivant.
Je ne pouvais pas obtenir la réponse acceptée qui fonctionnait pour moi (la grep
dans les guillemets ne fonctionnait pas), voici donc ma version:
RESULT=`mysql -u $USER -p$PASSWORD --skip-column-names -e "SHOW DATABASES LIKE 'myDatabase'"`
if [ "$RESULT" == "myDatabase" ]; then
echo "Database exist"
else
echo "Database does not exist"
fi
J'ai utilisé l'option --skip-column-names
pour supprimer les noms de colonne du résultat.
Voici une version alternative:
RESULT=`mysql -u$USER -p$PASSWORD -e "SHOW DATABASES" | grep $DATABASE`
if [ "$RESULT" == "$DATABASE" ]; then
echo "Database exist"
else
echo "Database does not exist"
fi
SI il existe une base de données nommée abcd
et que nous utilisons -Fo
après grep
, alors pour le résultat de la recherche de la base de données a
/ab
/abc
, le script affiche le résultat Database exist
.
OUI
for db in $(mysql -u -p -N <<<"show databases like '%something%'")
do
case $db in
"something")
// do something
;;
"something else")
// do something else
;;
esac
done
Une autre solution sans grep
:
FOUND_DATABASES=`MYSQL_PWD="${DB_PASSWORD}" mysql \
-u "${DB_PASSWORD}" \
--skip-column-names \
--batch \
-e "SHOW DATABASES LIKE '${DB_NAME}'" | wc -l`
FOUND_DATABASES :
Remarques:
MYSQL_PWD
pour désactiver l'avertissement:
mysql: [Avertissement] L'utilisation d'un mot de passe sur l'interface de ligne de commande peut ne pas être sûre.
--skip-column-names
pour masquer les colonnes
--batch
pour désactiver les bordures comme +-----------+
Il est assez facile de dire de manière fiable si la base de données existe avec mysqlshow. L'astuce consiste à pouvoir faire la différence de manière fiable entre une base de données pas existante ou un autre échec. La version de mysqlshow j'ai des sorties avec un '1' dans les deux cas, donc ça ne peut pas le dire.
Voici ce que je suis venu avec pour le gérer. Ajustez votre commande mysqlshow en conséquence, ou mettez vos informations d'identification dans un fichier chmod 600
'd ~/.my.cnf.
Cela fonctionne sur Ubuntu 12 + 14. Je ne l'ai pas encore testé dans d'autres environnements:
#!/bin/bash -u
# Takes 1 argument. Aborts the script if there's a false negative.
function mysql_db_exists () {
local DBNAME="$1"
# Underscores are treated as wildcards by mysqlshow.
# Replace them with '\\_'. One of the underscores is consumed by the Shell to keep the one mysqlshow needs in tact.
ESCAPED_DB_NAME="${DBNAME//_/\\\_}"
RESULT="$(mysqlshow "$ESCAPED_DB_NAME" 2>&1)"; EXITCODE=$?
if [ "$EXITCODE" -eq 0 ]; then
# This is never a false positive.
true
else
if echo "$RESULT" | grep -iq "Unknown database"; then
# True negative.
false
else
# False negative: Spit out the error and abort the script.
>&2 echo "ERR (mysql_db_exists): $RESULT"
exit 1
fi
fi
}
if mysql_db_exists "$1"; then
echo "It definitely exists."
else
echo "The only time you see this is when it positively does not."
fi
utilisez l'option -e
dans la commande mysql
. Il vous permettra d'exécuter n'importe quelle requête (en supposant que les informations d'identification sont correctes). Je ne connais pas de requête renvoyant uniquement le nom de la base de données. Vous devrez probablement analyser les résultats de show databases
ou show tables from dbname
.
Si cela peut aider, je l’ai fait pour MariaDB sur Debian Stretch:
DB_CHECK=$(mysqlshow "${DB_NAME}" | grep "Unknown database") 1> /dev/null
if [ ! -z "${DB_CHECK}" ]; then
echo "Database found."
else
echo "Database not found."
fi
Explication brève: le résultat de mysqlshow
pour le nom de la base de données dans la variable $DB_NAME
est vérifié pour "base de données inconnue" Si cette chaîne est trouvée, elle est placée dans la variable $DB_CHECK
. Enfin, la comparaison -z
vérifie si la variable $DB_CHECK
est vide.
Si $DB_CHECK
est vide, "Base de données inconnue" n'apparaît pas dans la réponse mysqlshow
. Probablement pas fiable à 100%, comme si la connexion échouait ou autre. (Je n'ai pas testé ça.)
FWIW, le plugin auth_socket
facilite beaucoup cela. La question est peut-être super vieille, mais il y a encore des gens comme moi qui viennent ici pour s’inspirer.
Si votre script est exécuté en tant que root, vous pouvez procéder comme suit:
DBNAME="what_you_are_looking_for"
DBEXISTS="$(mysql -u root -e "show databases like '$DBNAME'" --batch --skip-column-names)"
Si la base de données existe, alors $DBNAME = $DBEXISTS
.
Si la base de données n'existe pas, alors $DBEXISTS = ""
.
Les deux doivent avoir un statut de sortie égal à 0; vous pouvez donc toujours utiliser des statuts non nuls pour signaler les erreurs, au lieu de laisser une base de données inexistante apparaître comme une erreur.
La commande suivante devrait faire l'affaire pour les deux cas,
mysqlshow "DB_NAME" &> /dev/null && echo "YES" || echo "NO"
if [ $(mysqlshow DB 1>/dev/null 2>/dev/null) -eq 0 ]; then
echo "DB found"
fi
mysql_user=<you_db_username>
mysql_pass=<you_db_passwrod>
target_db=<your_db_name>
if [ "`mysql -u${mysql_user} -p${mysql_pass} -e 'show databases;' | grep ${target_db}`" == "${target_db}" ]; then
echo "Database exist"
else
echo "Database does not exist"
fi
Ceci exécute une requête MySQL pour obtenir tous les noms de base de données, puis greps pour vérifier que la base de données requise existe.
mysqlshow n'indiquera pas les caractères de soulignement '_' dans le nom de la base de données.
mysqlshow $DOMAIN %
Le chemin mysqlshow
nécessite l'analyse de la sortie (du moins pour la version de mysql que j'ai) car il renvoie toujours le succès. Dale souligne très bien la différence entre les échecs.
Cependant , si vous savez que tout est en cours d'exécution et que vous disposez des informations d'identification correctes, etc., et que vous souhaitez indiquer à uniquement si le DB existe, vous pouvez le faire en une ligne avec une commande sql vide:
> mysql -uroot -ppassword good_db -e ''
> echo $?
0
> mysql -uroot -ppassword bad_db -e ''
ERROR 1049 (42000): Unknown database 'busker_core_locala'
> echo $?
1