使用shell检查PostgreSQL中是否存在数据库

Jim*_*mmy 116 postgresql shell

我想知道是否有人能够告诉我是否可以使用shell来检查PostgreSQL数据库是否存在?

我正在制作一个shell脚本,我只希望它创建数据库,如果它尚不存在但到目前为止还没有看到如何实现它.

kib*_*ibu 184

我使用以下对Arturo解决方案的修改:

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)
Run Code Online (Sandbox Code Playgroud)

使用朴素方法意味着搜索名为"List"的数据库,"访问"或"行"将成功.因此,我们通过一堆内置命令行工具来管理此输出,仅在第一列中搜索.


-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
Run Code Online (Sandbox Code Playgroud)

下一位,cut -d \| -f 1通过垂直管道|字符(使用反斜杠从shell转义)拆分输出,并选择字段1.这将离开:

 my_db             
 postgres          
 template0         

 template1         
Run Code Online (Sandbox Code Playgroud)

grep -w匹配整个单词,因此如果您temp在此方案中搜索,则不匹配.该-q选项会禁止写入屏幕的任何输出,因此,如果要在命令提示符下以交互方式运行此输出,则可以将其排除,-q以便立即显示某些内容.

请注意,grep -w匹配字母数字,数字和下划线,这正是postgresql中不带引号的数据库名称中允许的字符集(连字符在不带引号的标识符中不合法).如果您使用其他角色,grep -w则不适合您.


0如果数据库存在,整个管道的退出状态将是(成功),否则将是1(失败).您的shell会将特殊变量设置$?为最后一个命令的退出状态.您还可以直接在条件中测试状态:

if psql -lqt | cut -d \| -f 1 | grep -qw <db_name>; then
    # database exists
    # $? is 0
else
    # ruh-roh
    # $? is 1
fi
Run Code Online (Sandbox Code Playgroud)

  • 你也可以添加`... | grep 0`使shell返回值为0,如果DB不存在则为1;如果DB存在则为1; 或``| grep 1`表示相反的行为 (8认同)
  • BTW,命令的优秀故障! (6认同)
  • @ acjohnson55甚至更好:完全放弃`wc`.看我的修订版.(如果你想反转退出状态,Bash支持一个bang操作符:`!psql ...`) (2认同)

Nat*_*man 68

以下shell代码似乎对我有用:

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
Run Code Online (Sandbox Code Playgroud)

  • 我喜欢你不依赖任何外部剪切 grep wc 之类的东西..你检查数据库是否存在,这大概意味着你至少有 psql,ant 这是你使用的最少且唯一的命令!的确很好。此外,主题没有提到 shell 类型,也没有提到命令版本或发行版。我永远不会将如此多的管道传递给我在其他答案上看到的系统工具。这会导致多年后的问题 (2认同)

Art*_*uro 26

postgres@desktop:~$ psql -l | grep <exact_dbname> | wc -l
Run Code Online (Sandbox Code Playgroud)

如果指定的数据库存在,则返回1,否则返回0.

此外,如果您尝试创建已存在的数据库,postgresql将返回如下错误消息:

postgres@desktop:~$ createdb template1
createdb: database creation failed: ERROR:  database "template1" already exists
Run Code Online (Sandbox Code Playgroud)

  • 第一个建议非常危险.将会出现`exact_dbname_test`会发生什么?唯一的测试方法是尝试连接它. (10认同)
  • 这个答案并不健全!如果您的搜索词出现在另一列中,它会打印(不返回!)非零数字.请参阅kibibu的答案以获得更正确的方法. (6认同)
  • "grep -w <exact_dbname>"应该做的诀窍:) (3认同)
  • 所有的切割是什么?如果你想确保只查看第一列,只需将它放在正则表达式中:`psql -l | grep'^ exact_dbname\b'`,如果找不到则设置退出代码. (2认同)

小智 19

我是postgresql的新手,但以下命令是我用来检查数据库是否存在的命令

if psql ${DB_NAME} -c '\q' 2>&1; then
   echo "database ${DB_NAME} exists"
fi
Run Code Online (Sandbox Code Playgroud)

  • 可以进一步简化为`psql $ {DB_NAME} -c''`. (8认同)
  • @SteveBennett,如果您对所需的数据库没有任何权限,那么它就不存在了:) (5认同)
  • 对我来说看起来不错,尽管如果数据库存在但您无法连接到它(可能是权限?) (2认同)

Oth*_*eus 10

我将其他答案与简洁和POSIX兼容的形式结合起来:

psql -lqtA | grep -q "^$DB_NAME|"
Run Code Online (Sandbox Code Playgroud)

返回true(0)表示它存在.

如果您怀疑数据库名称可能具有非标准字符$,则需要稍长的方法:

psql -lqtA | cut -d\| -f1 | grep -qxF "$DB_NAME"
Run Code Online (Sandbox Code Playgroud)

-t-A选项确保输出为原料,而不是"表格"或空白填充输出.列由管道字符分离|,因此无论是cutgrep具有识别这个.第一列包含数据库名称.

编辑:使用-x grep以防止部分名称匹配.


Nic*_*lly 8

您可以使用此方法创建数据库(如果尚不存在):

if [[ -z `psql -Atqc '\list mydatabase' postgres` ]]; then createdb mydatabase; fi
Run Code Online (Sandbox Code Playgroud)


wil*_*ser 5

#!/bin/sh
DB_NAME=hahahahahahaha
psql -U postgres ${DB_NAME} --command="SELECT version();" >/dev/null 2>&1
RESULT=$?
echo DATABASE=${DB_NAME} RESULT=${RESULT}
#
Run Code Online (Sandbox Code Playgroud)