Ich verwende die folgende Modifikation der Arturo-Lösung:
psql -lqt | cut -d \| -f 1 | grep -qw <db_name>
Was es macht
psql -l
gibt ungefähr Folgendes aus:
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)
Die Verwendung des naiven Ansatzes bedeutet, dass die Suche nach einer Datenbank mit den Namen "Liste", "Zugriff" oder "Zeilen" erfolgreich ist. Daher leiten wir diese Ausgabe durch eine Reihe integrierter Befehlszeilentools, um nur in der ersten Spalte zu suchen.
Die -t
Flagge entfernt Kopf- und Fußzeilen:
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
Das nächste Bit cut -d \| -f 1
teilt die Ausgabe durch das vertikale Pipe- |
Zeichen (das mit einem Backslash aus der Shell entfernt wurde) und wählt Feld 1 aus. Dies lässt Folgendes übrig:
my_db
postgres
template0
template1
grep -w
stimmt mit ganzen Wörtern überein und stimmt daher nicht überein, wenn Sie temp
in diesem Szenario suchen . Die -q
Option unterdrückt alle Ausgaben, die auf den Bildschirm geschrieben werden. Wenn Sie diese also interaktiv an einer Eingabeaufforderung ausführen möchten, können Sie die ausschließen, -q
damit sofort etwas angezeigt wird.
Beachten Sie, dass dies grep -w
mit alphanumerischen Zeichen, Ziffern und dem Unterstrich übereinstimmt. Dies ist genau der Zeichensatz, der in nicht zitierten Datenbanknamen in postgresql zulässig ist (Bindestriche sind in nicht zitierten Bezeichnern nicht zulässig). Wenn Sie andere Zeichen verwenden, grep -w
funktioniert dies nicht für Sie.
Der Exit-Status dieser gesamten Pipeline lautet 0
(Erfolg), wenn die Datenbank vorhanden ist, oder 1
(Fehler), wenn dies nicht der Fall ist. Ihre Shell setzt die spezielle Variable $?
auf den Exit-Status des letzten Befehls. Sie können den Status auch direkt in einer Bedingung testen:
if psql -lqt | cut -d \| -f 1 | grep -qw <db_name>; then
# database exists
# $? is 0
else
# ruh-roh
# $? is 1
fi
... | grep 0
, dass der Shell-Rückgabewert 0 ist, wenn die Datenbank nicht vorhanden ist, und 1, wenn dies der Fall ist. oder... | grep 1
für das gegenteilige Verhaltenwc
ganz fallen. Siehe meine Überarbeitung. (Wenn Sie den Exit - Status umkehren wollen, unterstützt Bash einen Knall Operator:! psql ...
)wc
Befehl fallen zu lassen , würde ich verwendengrep -qw <term>
. Dies führt dazu, dass die Shell zurückkehrt,0
wenn eine Übereinstimmung vorliegt und1
anderweitig. Enthält$?
dann den Rückgabewert und Sie können diesen verwenden, um zu entscheiden, was als nächstes zu tun ist. Daher empfehle ich,wc
in diesem Fall nicht zu verwenden .grep
wird tun, was Sie brauchen.Der folgende Shell-Code scheint für mich zu funktionieren:
quelle
psql -U user -tAc "SELECT 1 FROM pg_database WHERE datname='DB_NAME'" template1
if [[ $(...) == 1* ]]
Dies gibt 1 zurück, wenn die angegebene Datenbank vorhanden ist, oder 0, wenn dies nicht der Fall ist.
Wenn Sie versuchen, eine bereits vorhandene Datenbank zu erstellen, gibt postgresql eine Fehlermeldung wie die folgende zurück:
quelle
exact_dbname_test
würde existieren? Die einzige Möglichkeit zum Testen besteht darin, eine Verbindung herzustellen.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'
, der einen Exit-Code festlegt, wenn er nicht gefunden wird.Ich bin neu in postgresql, aber mit dem folgenden Befehl habe ich überprüft, ob eine Datenbank vorhanden ist
quelle
psql ${DB_NAME} -c ''
.Mit dieser Methode können Sie eine Datenbank erstellen, falls diese noch nicht vorhanden ist:
quelle
Ich kombiniere die anderen Antworten zu einer prägnanten und POSIX-kompatiblen Form:
Eine Rückgabe von
true
(0
) bedeutet, dass es existiert.Wenn Sie den Verdacht haben, dass Ihr Datenbankname ein nicht standardmäßiges Zeichen hat, wie z. B.
$
, benötigen Sie einen etwas längeren Ansatz:Die Optionen
-t
und-A
stellen sicher, dass die Ausgabe roh und nicht "tabellarisch" oder mit Leerzeichen aufgefüllte Ausgabe ist. Spalten werden durch das Pipe-Zeichen getrennt|
, sodass entweder dascut
oder dasgrep
dies erkennen muss. Die erste Spalte enthält den Datenbanknamen.BEARBEITEN: grep mit -x, um teilweise Namensübereinstimmungen zu verhindern.
quelle
quelle
Der Vollständigkeit halber eine andere Version, die Regex anstelle von Schnurschneiden verwendet:
Also zum Beispiel:
quelle
\b
hat das gleiche Problem wie alle Antworten, beigrep -w
denen Datenbanknamen Zeichen enthalten können, die keine Wortbestandteile enthalten,-
und daher stimmenfoo
auch Übereinstimmungsversuche übereinfoo-bar
.Die akzeptierte Antwort von kibibu ist insofern fehlerhaft, als
grep -w
sie mit jedem Namen übereinstimmt , der das angegebene Muster als Wortkomponente enthält.dh wenn Sie nach "foo" suchen, dann ist "foo-backup" eine Übereinstimmung.
Otheus 'Antwort bietet einige gute Verbesserungen, und die Kurzversion funktioniert in den meisten Fällen korrekt, aber die längere der beiden angebotenen Varianten weist ein ähnliches Problem mit passenden Teilzeichenfolgen auf.
Um dieses Problem zu beheben, können wir das POSIX-
-x
Argument verwenden, um nur die gesamte Übereinstimmung zu erzielen Textzeilen abzugleichen.Aufbauend auf Otheus 'Antwort sieht die neue Version folgendermaßen aus:
Trotzdem bin ich geneigt zu sagen, dass die Antwort von Nicolas Grilly - bei der Sie tatsächlich Postgres nach der spezifischen Datenbank fragen - der beste Ansatz von allen ist.
quelle
Die anderen Lösungen (die fantastisch sind) übersehen die Tatsache, dass psql eine Minute oder länger warten kann, bevor eine Zeitüberschreitung auftritt, wenn keine Verbindung zu einem Host hergestellt werden kann. Ich mag diese Lösung, bei der das Zeitlimit auf 3 Sekunden festgelegt wird:
Dies dient zum Herstellen einer Verbindung zu einer Entwicklungsdatenbank auf dem offiziellen Postgres Alpine Docker-Image.
Wenn Sie Rails verwenden und eine Datenbank einrichten möchten, falls diese noch nicht vorhanden ist (wie beim Starten eines Docker-Containers), funktioniert dies gut, da Migrationen idempotent sind:
quelle
psql -l|awk '{print $1}'|grep -w <database>
kürzere Version
quelle
Ich bin immer noch ziemlich unerfahren mit Shell-Programmierung. Wenn dies aus irgendeinem Grund wirklich falsch ist, stimmen Sie mich ab, aber seien Sie nicht zu beunruhigt.
Aufbauend auf Kibibus Antwort:
quelle