J'utilise la modification suivante de la solution d'Arturo:
psql -lqt | cut -d \| -f 1 | grep -qw <db_name>
Ce qu'il fait
psql -l
produit quelque chose comme ce qui suit:
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+-----------+----------+------------+------------+-----------------------
my_db | my_user | UTF8 | en_US.UTF8 | en_US.UTF8 |
postgres | postgres | LATIN1 | en_US | en_US |
template0 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
(4 rows)
L'utilisation de l'approche naïve signifie que la recherche d'une base de données appelée "Liste," Accès "ou" lignes "réussira. Nous acheminons donc cette sortie à travers un ensemble d'outils de ligne de commande intégrés pour rechercher uniquement dans la première colonne.
L' -t
indicateur supprime les en-têtes et les pieds de page:
my_db | my_user | UTF8 | en_US.UTF8 | en_US.UTF8 |
postgres | postgres | LATIN1 | en_US | en_US |
template0 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | LATIN1 | en_US | en_US | =c/postgres +
| | | | | postgres=CTc/postgres
Le bit suivant cut -d \| -f 1
divise la sortie par le |
caractère de tube vertical (échappé du shell avec une barre oblique inverse), et sélectionne le champ 1. Cela laisse:
my_db
postgres
template0
template1
grep -w
correspond à des mots entiers et ne correspondra donc pas si vous recherchez temp
dans ce scénario. L' -q
option supprime toute sortie écrite à l'écran, donc si vous voulez l'exécuter de manière interactive à une invite de commande, vous pouvez avec pour exclure le -q
afin que quelque chose soit affiché immédiatement.
Notez qu'il grep -w
correspond aux caractères alphanumériques, aux chiffres et au trait de soulignement, qui est exactement le jeu de caractères autorisé dans les noms de base de données non entre guillemets dans postgresql (les tirets ne sont pas autorisés dans les identifiants non entre guillemets). Si vous utilisez d'autres personnages, grep -w
cela ne fonctionnera pas pour vous.
Le statut de sortie de tout ce pipeline sera 0
(succès) si la base de données existe ou 1
(échec) si ce n'est pas le cas. Votre shell définira la variable spéciale $?
sur l'état de sortie de la dernière commande. Vous pouvez également tester le statut directement dans un conditionnel:
if psql -lqt | cut -d \| -f 1 | grep -qw <db_name>; then
# database exists
# $? is 0
else
# ruh-roh
# $? is 1
fi
... | grep 0
pour que la valeur de retour du shell soit 0 si le DB n'existe pas et 1 s'il existe; ou... | grep 1
pour le comportement opposéwc
tout. Voir ma révision. (Si vous voulez inverser l'état de sortie, Bash prend en charge un opérateur bang:! psql ...
)wc
commande, j'utiliseraisgrep -qw <term>
. Cela entraînera le retour du shell0
s'il y a une correspondance et1
sinon. Ensuite,$?
contiendra la valeur de retour et vous pourrez l'utiliser pour décider quoi faire ensuite. Donc, je recommande de ne pas utiliserwc
dans ce cas.grep
fera ce dont vous avez besoin.Le code shell suivant semble fonctionner pour moi:
la source
psql -U user -tAc "SELECT 1 FROM pg_database WHERE datname='DB_NAME'" template1
if [[ $(...) == 1* ]]
Cela renverra 1 si la base de données spécifiée existe ou 0 sinon.
De plus, si vous essayez de créer une base de données qui existe déjà, postgresql renverra un message d'erreur comme celui-ci:
la source
exact_dbname_test
exister? La seule façon de tester est d'essayer de s'y connecter.psql -l | grep doesnt_matter_what_you_grep | wc -l && echo "true"
vspsql -l | grep it_does_matter_here && echo "only true if grep returns anything"
psql -l | grep '^ exact_dbname\b'
qui définit un code de sortie s'il n'est pas trouvé.Je suis nouveau sur postgresql, mais la commande suivante est ce que j'ai utilisé pour vérifier si une base de données existe
la source
psql ${DB_NAME} -c ''
.Vous pouvez créer une base de données, si elle n'existe pas déjà, en utilisant cette méthode:
la source
Je combine les autres réponses dans un formulaire succinct et compatible POSIX:
Un retour de
true
(0
) signifie qu'il existe.Si vous pensez que le nom de votre base de données pourrait avoir un caractère non standard tel que
$
, vous avez besoin d'une approche légèrement plus longue:Les options
-t
et-A
s'assurent que la sortie est brute et non "tabulaire" ou remplie d'espaces. Les colonnes sont séparées par le caractère pipe|
, donc lecut
ou legrep
doit le reconnaître. La première colonne contient le nom de la base de données.EDIT: grep avec -x pour éviter les correspondances partielles de nom.
la source
la source
Pour être complet, une autre version utilisant regex plutôt que la coupe de chaîne:
Donc par exemple:
la source
\b
pose le même problème que toutes les réponses utilisant,grep -w
c'est-à-dire que les noms de base de données peuvent contenir des caractères non constitutifs de mots comme-
et donc les tentatives de correspondance correspondentfoo
égalementfoo-bar
.La réponse acceptée de kibibu est imparfaite car
grep -w
elle correspondra à tout nom contenant le modèle spécifié en tant que composant de mot.c'est-à-dire que si vous recherchez "foo", "foo-backup" est une correspondance.
La réponse d'Otheus apporte de bonnes améliorations et la version courte fonctionnera correctement dans la plupart des cas, mais la plus longue des deux variantes proposées présente un problème similaire avec les sous-chaînes correspondantes.
Pour résoudre ce problème, nous pouvons utiliser l'
-x
argument POSIX pour ne faire correspondre que des lignes entières du texte.S'appuyant sur la réponse d'Otheus, la nouvelle version ressemble à ceci:
Cela dit, j'ai tendance à dire que la réponse de Nicolas Grilly - où vous posez en fait des questions à postgres sur la base de données spécifique - est la meilleure approche de toutes.
la source
Les autres solutions (qui sont fantastiques) passent à côté du fait que psql peut attendre une minute ou plus avant d'expirer s'il ne peut pas se connecter à un hôte. Donc, j'aime cette solution, qui définit le délai d'expiration à 3 secondes:
Ceci permet de se connecter à une base de données de développement sur l'image officielle postgres Alpine Docker.
Séparément, si vous utilisez Rails et que vous souhaitez configurer une base de données si elle n'existe pas déjà (comme lors du lancement d'un conteneur Docker), cela fonctionne bien, car les migrations sont idempotentes:
la source
psql -l|awk '{print $1}'|grep -w <database>
version plus courte
la source
Je suis encore assez inexpérimenté avec la programmation shell, donc si c'est vraiment faux pour une raison quelconque, votez-moi, mais ne vous inquiétez pas trop.
Construire à partir de la réponse de Kibibu:
la source