Utilizo la siguiente modificación de la solución de Arturo:
psql -lqt | cut -d \| -f 1 | grep -qw <db_name>
Que hace
psql -l
produce algo como lo siguiente:
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 el enfoque ingenuo significa que la búsqueda de una base de datos llamada "Lista", "Acceso" o "filas" tendrá éxito. Por lo tanto, canalizamos esta salida a través de un conjunto de herramientas de línea de comando integradas para buscar solo en la primera columna.
La -t
bandera elimina encabezados y pies de página:
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
El siguiente bit, cut -d \| -f 1
divide la salida por el |
carácter de tubería vertical (escapado del shell con una barra invertida), y selecciona el campo 1. Esto deja:
my_db
postgres
template0
template1
grep -w
coincide con palabras completas, por lo que no coincidirá si está buscando temp
en este escenario. La -q
opción suprime cualquier salida escrita en la pantalla, por lo que si desea ejecutar esto interactivamente en un símbolo del sistema, puede excluirlo -q
para que algo se muestre de inmediato.
Tenga en cuenta que grep -w
coincide con los caracteres alfanuméricos, los dígitos y el guión bajo, que es exactamente el conjunto de caracteres permitidos en los nombres de bases de datos sin comillas en postgresql (los guiones no son legales en los identificadores sin comillas). Si está utilizando otros personajes, grep -w
no funcionará para usted.
El estado de salida de toda esta tubería será 0
(exitoso) si la base de datos existe o 1
(falla) si no existe. Su shell establecerá la variable especial $?
en el estado de salida del último comando. También puede probar el estado directamente en un condicional:
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 hacer que el valor de retorno del shell sea 0 si la base de datos no existe y 1 si existe; o... | grep 1
por el comportamiento opuestowc
completo. Mira mi revisión. (Si desea revertir el estado de salida, Bash soporta un operador de explosión:! psql ...
)wc
comando, usaríagrep -qw <term>
. Esto hará que el shell regrese0
si hay una coincidencia y de lo1
contrario. Luego,$?
contendrá el valor de retorno y puede usarlo para decidir qué hacer a continuación. Por lo tanto, recomiendo no usarwc
en este caso.grep
Hará lo que necesite.El siguiente código de shell parece funcionar para mí:
fuente
psql -U user -tAc "SELECT 1 FROM pg_database WHERE datname='DB_NAME'" template1
if [[ $(...) == 1* ]]
Esto devolverá 1 si la base de datos especificada existe o 0 en caso contrario.
Además, si intenta crear una base de datos que ya existe, postgresql devolverá un mensaje de error como este:
fuente
exact_dbname_test
existir? La única forma de probar es intentar conectarse a él.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 establece un código de salida si no se encuentra.Soy nuevo en postgresql, pero el siguiente comando es lo que solía verificar si existe una base de datos
fuente
psql ${DB_NAME} -c ''
.Puede crear una base de datos, si aún no existe, utilizando este método:
fuente
Estoy combinando las otras respuestas a una forma sucinta y compatible con POSIX:
Un retorno de
true
(0
) significa que existe.Si sospecha que el nombre de su base de datos puede tener un carácter no estándar como
$
, necesita un enfoque un poco más largo:Las opciones
-t
y-A
aseguran que la salida sea sin formato y no "tabular" o con espacios en blanco. Las columnas están separadas por el carácter de la tubería|
, por lo que elcut
o elgrep
tiene que reconocer esto. La primera columna contiene el nombre de la base de datos.EDITAR: grep con -x para evitar coincidencias parciales de nombres.
fuente
fuente
Para completar, otra versión que usa expresiones regulares en lugar de cortar cadenas:
Entonces, por ejemplo:
fuente
\b
tiene el mismo problema que todas las respuestasgrep -w
que usan que es que los nombres de bases de datos pueden contener caracteres que no son constituyentes de palabras-
y, por lo tanto, los intentos de coincidenciafoo
también coincidiránfoo-bar
.La respuesta aceptada de kibibu es errónea, ya que
grep -w
coincidirá con cualquier nombre que contenga el patrón especificado como un componente de palabra.es decir, si busca "foo", entonces "foo-backup" es una coincidencia.
La respuesta de Otheus proporciona algunas buenas mejoras, y la versión corta funcionará correctamente en la mayoría de los casos, pero la más larga de las dos variantes ofrecidas exhibe un problema similar con las subcadenas coincidentes.
Para resolver este problema, podemos usar el
-x
argumento POSIX para hacer coincidir solo líneas enteras del texto.Sobre la base de la respuesta de Otheus, la nueva versión se ve así:
Dicho todo esto, me inclino a decir que la respuesta de Nicolas Grilly, donde realmente le preguntas a postgres sobre la base de datos específica, es el mejor enfoque de todos.
fuente
Las otras soluciones (que son fantásticas) pierden el hecho de que psql puede esperar un minuto o más antes de que se agote el tiempo de espera si no puede conectarse a un host. Entonces, me gusta esta solución, que establece el tiempo de espera en 3 segundos:
Esto es para conectarse a una base de datos de desarrollo en la imagen oficial de Postgres Alpine Docker.
Por separado, si está utilizando Rails y desea configurar una base de datos si aún no existe (como al iniciar un contenedor Docker), esto funciona bien, ya que las migraciones son idempotentes:
fuente
psql -l|awk '{print $1}'|grep -w <database>
versión corta
fuente
Todavía no tengo mucha experiencia con la programación de shell, por lo que si esto está realmente mal por alguna razón, desestime mi voto, pero no se alarme demasiado.
Partiendo de la respuesta de kibibu:
fuente