Stosuję następującą modyfikację rozwiązania Arturo:
psql -lqt | cut -d \| -f 1 | grep -qw <db_name>
Co to robi
psql -l
wyświetla coś podobnego do następującego:
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)
Korzystanie z naiwnego podejścia oznacza, że wyszukiwanie bazy danych o nazwie „Lista,„ Dostęp ”lub„ wiersze ”zakończy się sukcesem. Dlatego przesyłamy te dane wyjściowe za pomocą zestawu wbudowanych narzędzi wiersza poleceń, aby wyszukiwać tylko w pierwszej kolumnie.
-t
Flag usuwa nagłówków i stopek:
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
Następny bit cut -d \| -f 1
dzieli dane wyjściowe za pomocą pionowej kreski |
(uciekającej z powłoki z ukośnikiem odwrotnym) i wybiera pole 1. To pozostawia:
my_db
postgres
template0
template1
grep -w
dopasowuje całe słowa, więc nie będzie pasować, jeśli szukasz temp
w tym scenariuszu. Ta -q
opcja blokuje wszelkie dane wyjściowe zapisywane na ekranie, więc jeśli chcesz uruchomić to interaktywnie w wierszu polecenia, możesz wykluczyć to, -q
aby coś zostało natychmiast wyświetlone.
Zwróć uwagę, że grep -w
dopasowuje znaki alfanumeryczne, cyfry i podkreślenie, co jest dokładnie zestawem znaków dozwolonym w niecytowanych nazwach baz danych w postgresql (łączniki nie są dozwolone w niecytowanych identyfikatorach). Jeśli używasz innych znaków, grep -w
nie zadziała.
Status wyjścia tego całego potoku będzie 0
(powodzenie), jeśli baza danych istnieje lub 1
(błąd), jeśli tak nie jest. Twoja powłoka ustawi specjalną zmienną $?
na kod zakończenia ostatniego polecenia. Możesz również sprawdzić status bezpośrednio w warunku:
if psql -lqt | cut -d \| -f 1 | grep -qw <db_name>; then
else
fi
... | grep 0
aby wartość zwracana przez powłokę wynosiła 0, jeśli baza danych nie istnieje, i 1, jeśli tak; lub... | grep 1
dla odwrotnego zachowaniawc
całkowicie. Zobacz moją wersję. (Jeśli chcesz, aby odwrócić stan wyjścia, Bash obsługuje operator Bang:! psql ...
)wc
polecenie, użyłbymgrep -qw <term>
. Spowoduje to, że powłoka powróci,0
jeśli istnieje dopasowanie lub w1
przeciwnym razie. Następnie$?
będzie zawierał wartość zwracaną i możesz na jej podstawie zdecydować, co dalej. Dlatego polecam nie używaćwc
w tym przypadku.grep
zrobi to, czego potrzebujesz.Wydaje się, że działa dla mnie następujący kod powłoki:
if [ "$( psql -tAc "SELECT 1 FROM pg_database WHERE datname='DB_NAME'" )" = '1' ] then echo "Database already exists" else echo "Database does not exist" fi
źródło
psql -U user -tAc "SELECT 1 FROM pg_database WHERE datname='DB_NAME'" template1
if [[ $(...) == 1* ]]
postgres@desktop:~$ psql -l | grep <exact_dbname> | wc -l
Zwróci to 1, jeśli określona baza danych istnieje lub 0 w przeciwnym razie.
Ponadto, jeśli spróbujesz utworzyć bazę danych, która już istnieje, postgresql zwróci komunikat o błędzie podobny do tego:
postgres@desktop:~$ createdb template1 createdb: database creation failed: ERROR: database "template1" already exists
źródło
exact_dbname_test
gdyby istniało? Jedynym sposobem przetestowania jest próba połączenia się z nim.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'
które ustawia kod zakończenia, jeśli nie zostanie znaleziony.Jestem nowy w Postgresql, ale poniższe polecenie jest tym, czego użyłem do sprawdzenia, czy baza danych istnieje
if psql ${DB_NAME} -c '\q' 2>&1; then echo "database ${DB_NAME} exists" fi
źródło
psql ${DB_NAME} -c ''
.Możesz stworzyć bazę danych, jeśli jeszcze nie istnieje, używając tej metody:
if [[ -z `psql -Atqc '\list mydatabase' postgres` ]]; then createdb mydatabase; fi
źródło
Łączę inne odpowiedzi w zwięzłą i zgodną z POSIX formę:
psql -lqtA | grep -q "^$DB_NAME|"
Zwrot
true
(0
) oznacza, że istnieje.Jeśli podejrzewasz, że nazwa Twojej bazy danych może mieć niestandardowy znak, taki jak
$
, potrzebujesz nieco dłuższego podejścia:psql -lqtA | cut -d\| -f1 | grep -qxF "$DB_NAME"
-t
I-A
opcji upewnij się, że wyjście jest surowy, a nie „tabelaryczne” lub wyjście spacje wyściełane. Kolumny są oddzielone przez postać rury|
, więc albocut
czygrep
ma to rozpoznać. Pierwsza kolumna zawiera nazwę bazy danych.EDYCJA: grep z -x, aby zapobiec dopasowaniu częściowych nazw.
źródło
#!/bin/sh DB_NAME=hahahahahahaha psql -U postgres ${DB_NAME} --command="SELECT version();" >/dev/null 2>&1 RESULT=$? echo DATABASE=${DB_NAME} RESULT=${RESULT} #
źródło
Dla kompletności, inna wersja używająca wyrażenia regularnego zamiast cięcia ciągów:
psql -l | grep '^ exact_dbname\b'
Na przykład:
if psql -l | grep '^ mydatabase\b' > /dev/null ; then echo "Database exists already." exit fi
źródło
\b
ma ten sam problem, co wszystkie odpowiedzi, wgrep -w
których nazwy baz danych mogą zawierać znaki niebędące składnikami słowa, takie jak-
i dlatego próby dopasowaniafoo
również będą pasowaćfoo-bar
.zaakceptowana odpowiedź kibibu jest błędna i
grep -w
będzie pasować do dowolnej nazwy zawierającej określony wzorzec jako składnik słowa.tzn. jeśli szukasz "foo", wtedy "foo-backup" jest dopasowaniem.
Odpowiedź Otheusa zapewnia kilka dobrych ulepszeń, a krótka wersja będzie działać poprawnie w większości przypadków, ale dłuższy z dwóch oferowanych wariantów wykazuje podobny problem z dopasowaniem podciągów.
Aby rozwiązać ten problem, możemy użyć
-x
argumentu POSIX, aby dopasować tylko całe linie tekstu.Opierając się na odpowiedzi Otheusa, nowa wersja wygląda następująco:
psql -U "$USER" -lqtA | cut -d\| -f1 | grep -qFx "$DBNAME"
To powiedziawszy, jestem skłonny powiedzieć, że odpowiedź Nicolasa Grilly'ego - w której faktycznie pytasz postgres o konkretną bazę danych - jest najlepszym podejściem ze wszystkich.
źródło
Inne rozwiązania (które są fantastyczne) pomijają fakt, że psql może odczekać minutę lub dłużej przed upływem limitu czasu, jeśli nie może połączyć się z hostem. Podoba mi się więc to rozwiązanie, które ustawia limit czasu na 3 sekundy:
PGCONNECT_TIMEOUT=3 psql development -h db -U postgres -c ""
Służy do łączenia się z bazą danych programistycznych na oficjalnym obrazie postgres Alpine Docker.
Osobno, jeśli używasz Railsów i chcesz skonfigurować bazę danych, jeśli jeszcze nie istnieje (jak podczas uruchamiania kontenera Docker), działa to dobrze, ponieważ migracje są idempotentne:
bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:setup
źródło
psql -l|awk '{print $1}'|grep -w <database>
krótsza wersja
źródło
Nadal nie mam doświadczenia w programowaniu powłoki, więc jeśli z jakiegoś powodu jest to naprawdę złe, oceń mnie, ale nie przejmuj się zbytnio.
Budowanie na podstawie odpowiedzi kibibu:
# If resulting string is not zero-length (not empty) then... if [[ ! -z `psql -lqt | cut -d \| -f 1 | grep -w $DB_NAME` ]]; then echo "Database $DB_NAME exists." else echo "No existing databases are named $DB_NAME." fi
źródło
PGPASSWORD=mypassword psql -U postgres@hostname -h postgres.hostname.com -tAc 'select 1' -d dbnae || echo 0
Zwróci to 1, jeśli db istnieje 0, jeśli nie
if [ "$(PGPASSWORD=mypassword psql -U postgres@hostname -h postgres.hostname.com -tAc 'select 1' -d dbnae || echo 0 )" = '1' ] then echo "Database already exists" else echo "Database does not exist" fi
źródło
Wyzwalacz podziel przez zero, jeśli nie istnieje, sprawdź kod powrotu w ten sposób:
sql="SELECT 1/count(*) FROM pg_database WHERE datname='db_name'"; error=$(psql -h host -U user -c "$sql" postgres); if $error then echo "doesn't exist"; else echo "exists"; fi
źródło