Я использую следующую модификацию решения Артуро:
psql -lqt | cut -d \| -f 1 | grep -qw <db_name>
Что оно делает
psql -l
выводит что-то вроде следующего:
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)
Использование наивного подхода означает, что поиск базы данных с именем «Список», «Доступ» или «Строки» будет успешным. Поэтому мы направляем этот вывод через набор встроенных инструментов командной строки, чтобы искать только в первом столбце.
-t
Флаг удаляет верхние и нижние колонтитулы:
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
Следующий бит cut -d \| -f 1
разделяет вывод вертикальной |
чертой (экранирован из оболочки обратной косой чертой) и выбирает поле 1. Это оставляет:
my_db
postgres
template0
template1
grep -w
соответствует целым словам, поэтому не будет соответствовать, если вы ищете temp
в этом сценарии. Эта -q
опция подавляет любой вывод, выводимый на экран, поэтому, если вы хотите запустить это в интерактивном режиме в командной строке, вы можете исключить, -q
чтобы что-то отображалось немедленно.
Обратите внимание, что grep -w
соответствует буквенно-цифровым цифрам, цифрам и подчеркиванию, что в точности соответствует набору символов, разрешенных в именах баз данных без кавычек в postgresql (дефисы недопустимы в идентификаторах без кавычек). Если вы используете других персонажей, у grep -w
вас не получится.
Статус выхода всего этого конвейера будет 0
(успех), если база данных существует, или 1
(сбой), если нет. Ваша оболочка установит для специальной переменной $?
статус выхода последней команды. Вы также можете проверить статус прямо в условном выражении:
if psql -lqt | cut -d \| -f 1 | grep -qw <db_name>; then
# database exists
# $? is 0
else
# ruh-roh
# $? is 1
fi
... | grep 0
чтобы возвращаемое значение оболочки равнялось 0, если БД не существует, и 1, если она существует; или... | grep 1
для противоположного поведенияwc
полностью отказаться от этого . Смотрите мою ревизию. (Если вы хотите , чтобы изменить статус выхода, Bash поддерживает оператор челки:! psql ...
)wc
команды, я бы использовалgrep -qw <term>
. Это приведет к тому, что оболочка вернется,0
если есть совпадение, и в1
противном случае. Затем$?
будет содержать возвращаемое значение, и вы можете использовать его, чтобы решить, что делать дальше. Поэтому я рекомендую не использоватьwc
в этом случае.grep
сделаю то, что вам нужно.Мне кажется, что мне подходит следующий код оболочки:
источник
psql -U user -tAc "SELECT 1 FROM pg_database WHERE datname='DB_NAME'" template1
if [[ $(...) == 1* ]]
Это вернет 1, если указанная база данных существует, или 0 в противном случае.
Кроме того, если вы попытаетесь создать базу данных, которая уже существует, postgresql вернет сообщение об ошибке, подобное этому:
источник
exact_dbname_test
существующим? Единственный способ тестирования - это попытаться подключиться к нему.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'
которое устанавливает код выхода, если он не найден.Я новичок в postgresql, но я использовал следующую команду, чтобы проверить, существует ли база данных
источник
psql ${DB_NAME} -c ''
.Вы можете создать базу данных, если она еще не существует, используя этот метод:
источник
Я объединяю другие ответы в сжатую и совместимую с POSIX форму:
Возврат
true
(0
) означает, что он существует.Если вы подозреваете, что имя вашей базы данных может иметь нестандартный символ, например
$
, вам нужен немного более длинный подход:Параметры
-t
и-A
гарантируют, что вывод будет необработанным, а не "табличным" или заполненным пробелами. Столбцы разделяются вертикальной чертой|
, так чтоcut
этоgrep
должно распознаваться либо символом , либо символом . Первый столбец содержит имя базы данных.РЕДАКТИРОВАТЬ: grep с -x, чтобы предотвратить частичное совпадение имен.
источник
источник
Для полноты, другая версия, использующая регулярное выражение, а не вырезание строки:
Так например:
источник
\b
имеет ту же проблему, что и все ответы с использованием,grep -w
которые заключаются в том, что имена баз данных могут содержать символы, не входящие в состав слова, например,-
и поэтому попытки сопоставленияfoo
также будут совпадатьfoo-bar
.Принятый ответ kibibu ошибочен в том, что он
grep -w
будет соответствовать любому имени, содержащему указанный шаблон в качестве компонента слова.т.е. если вы ищите "foo", тогда "foo-backup" будет подходящим.
Ответ Отеуса дает некоторые хорошие улучшения, и короткая версия будет работать правильно в большинстве случаев, но более длинный из двух предложенных вариантов вызывает аналогичную проблему с сопоставлением подстрок.
Чтобы решить эту проблему, мы можем использовать
-x
аргумент POSIX для сопоставления только целых строк текста.Основываясь на ответе Отеуса, новая версия выглядит так:
С учетом всего сказанного, я склонен сказать, что ответ Николаса Грилли - когда вы фактически спрашиваете postgres о конкретной базе данных - является лучшим подходом из всех.
источник
В других решениях (которые просто фантастичны) упускается из виду тот факт, что psql может подождать минуту или больше, прежде чем истечет время ожидания, если он не может подключиться к хосту. Итак, мне нравится это решение, которое устанавливает тайм-аут на 3 секунды:
Это для подключения к базе данных разработки на официальном образе Postgres Alpine Docker.
Отдельно, если вы используете Rails и хотите настроить базу данных, если она еще не существует (например, при запуске контейнера Docker), это хорошо работает, поскольку миграции идемпотентны:
источник
psql -l|awk '{print $1}'|grep -w <database>
более короткая версия
источник
Я все еще не очень разбираюсь в программировании оболочки, поэтому, если по какой-то причине это действительно неправильно, проголосуйте за меня, но не пугайтесь.
Построение из ответа Кибибу:
источник