Eu uso a seguinte modificação da solução do Arturo:
psql -lqt | cut -d \| -f 1 | grep -qw <db_name>
O que faz
psql -l
gera algo como o seguinte:
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)
Usar uma abordagem ingênua significa que a busca por um banco de dados chamado "Lista", "Acesso" ou "linhas" será bem-sucedida. Portanto, canalizamos essa saída através de várias ferramentas de linha de comando internas para pesquisar apenas na primeira coluna.
A -t
bandeira remove cabeçalhos e rodapés:
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
O próximo bit cut -d \| -f 1
divide a saída pelo |
caractere de tubo vertical (escapou do shell com uma barra invertida) e seleciona o campo 1. Isso deixa:
my_db
postgres
template0
template1
grep -w
corresponde a palavras inteiras e, portanto, não corresponderá se você estiver pesquisando temp
nesse cenário. A -q
opção suprime qualquer saída gravada na tela; portanto, se você deseja executá-lo interativamente em um prompt de comando, pode excluir o valor-q
item para que algo seja exibido imediatamente.
Observe que grep -w
corresponde a alfanuméricos, dígitos e o sublinhado, que é exatamente o conjunto de caracteres permitido nos nomes de banco de dados não citados no postgresql (hífens não são legais em identificadores não citados). Se você estiver usando outros caracteres, grep -w
não funcionará para você.
O status de saída de todo esse pipeline será 0
(êxito) se o banco de dados existir ou 1
(falha) se não existir . Seu shell definirá a variável especial $?
para o status de saída do último comando. Você também pode testar o status diretamente em uma condição:
if psql -lqt | cut -d \| -f 1 | grep -qw <db_name>; then
# database exists
# $? is 0
else
# ruh-roh
# $? is 1
fi
... | grep 0
para fazer com que o valor de retorno do shell seja 0 se o banco de dados não existir e 1 se existir; ou... | grep 1
para o comportamento opostowc
inteiramente. Veja minha revisão. (Se você quiser reverter o status de saída, Bash suporta um operador de estrondo:! psql ...
)wc
comando, eu usariagrep -qw <term>
. Isso fará com que o shell retorne0
se houver uma correspondência ou1
não. Em seguida,$?
conterá o valor de retorno e você poderá usá-lo para decidir o que fazer a seguir. Portanto, eu recomendo não usarwc
neste caso.grep
fará o que você precisa.O seguinte código shell parece funcionar para mim:
fonte
psql -U user -tAc "SELECT 1 FROM pg_database WHERE datname='DB_NAME'" template1
if [[ $(...) == 1* ]]
Isso retornará 1 se o banco de dados especificado existir ou 0 caso contrário.
Além disso, se você tentar criar um banco de dados que já existe, o postgresql retornará uma mensagem de erro como esta:
fonte
exact_dbname_test
existiria? A única maneira de testar é tentar se conectar a ele.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'
que define um código de saída se não for encontrado.Eu sou novo no postgresql, mas o comando a seguir é o que eu costumava verificar se existe um banco de dados
fonte
psql ${DB_NAME} -c ''
.Você pode criar um banco de dados, se ele ainda não existir, usando este método:
fonte
Estou combinando as outras respostas para um formulário sucinto e compatível com POSIX:
Um retorno de
true
(0
) significa que existe.Se você suspeitar que o nome do banco de dados possa ter um caractere não padrão, por exemplo
$
, precisará de uma abordagem um pouco mais:As opções
-t
e-A
garantem que a saída seja bruta e não "tabular" ou preenchida com espaço em branco. As colunas são separadas pelo caractere de barra vertical|
, portanto, ocut
ou ogrep
deve reconhecer isso. A primeira coluna contém o nome do banco de dados.EDIT: grep com -x para evitar correspondências parciais de nomes.
fonte
fonte
Para completar, outra versão usando regex, em vez de corte de cadeia:
Então, por exemplo:
fonte
\b
tem o mesmo problema que todas as respostasgrep -w
que usam, como nomes de bancos de dados podem conter caracteres que não sejam constituintes de palavras-
e, portanto, as tentativas de correspondênciafoo
também serão correspondentesfoo-bar
.A resposta aceita de kibibu é falha, pois
grep -w
corresponde a qualquer nome que contenha o padrão especificado como um componente de palavra.ou seja, se você procurar "foo", então "foo-backup" é uma correspondência.
Resposta de Otheus fornece algumas boas melhorias, e a versão curta funcionará corretamente na maioria dos casos, mas a mais longa das duas variantes oferecidas exibe um problema semelhante com a correspondência de substrings.
Para resolver esse problema, podemos usar o
-x
argumento POSIX para corresponder apenas a linhas inteiras do texto.Com base na resposta de Otheus, a nova versão fica assim:
Dito isso, estou inclinado a dizer que a resposta de Nicolas Grilly - onde você realmente pergunta ao postgres sobre o banco de dados específico - é a melhor abordagem de todas.
fonte
As outras soluções (que são fantásticas) perdem o fato de que o psql pode esperar um minuto ou mais antes de atingir o tempo limite, se não conseguir se conectar a um host. Então, eu gosto desta solução, que define o tempo limite para 3 segundos:
Isso é para conectar-se a um banco de dados de desenvolvimento na imagem oficial do Alpine Docker do postgres .
Separadamente, se você estiver usando o Rails e quiser configurar um banco de dados, se ele ainda não existir (como ao iniciar um contêiner do Docker), isso funcionará bem, pois as migrações são idempotentes:
fonte
psql -l|awk '{print $1}'|grep -w <database>
versão mais curta
fonte
Eu ainda sou bastante inexperiente com a programação de shell, por isso, se isso estiver realmente errado por algum motivo, vote-me, mas não fique muito alarmado.
Construindo a partir da resposta de kibibu:
fonte