注/更新(2021年):虽然这个答案可行,但从哲学上讲,我同意其他评论者的观点,正确的方法是询问Postgres。
检查是否有使用psql -c
或--command
的其他答案更适合您的用例(例如Nicholas Grilly's,Nathan Osman's,bruce's或Pedro's variant)
我使用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)
-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
通过竖杠|
字符(用反斜杠从shell中转义)分割输出,并选择第1个字段。这将留下以下内容: my_db
postgres
template0
template1
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
if [ "$( psql -XtAc "SELECT 1 FROM pg_database WHERE datname='DB_NAME'" )" = '1' ]
then
echo "Database already exists"
else
echo "Database does not exist"
fi
关于上面给出的psql
标志的快速帮助:
General options:
-c, --command=COMMAND run only single command (SQL or internal) and exit
-X, --no-psqlrc do not read startup file (~/.psqlrc)
Output format options:
-A, --no-align unaligned table output mode
-t, --tuples-only print rows only
psql -U user -tAc“SELECT 1 FROM pg_database WHERE datname ='DB_NAME'”template1
- janif [[ $(...) == 1* ]]
- janpostgres@desktop:~$ psql -l | grep <exact_dbname> | wc -l
如果指定的数据库存在,这将返回1;否则返回0。
此外,如果您尝试创建已经存在的数据库,PostgreSQL将返回如下错误消息:
postgres@desktop:~$ createdb template1
createdb: database creation failed: ERROR: database "template1" already exists
exact_dbname_test
存在会发生什么?唯一的测试方法是尝试连接它。 - wildplasserpsql -l | grep doesnt_matter_what_you_grep | wc -l && echo "true"
与psql -l | grep it_does_matter_here && echo "only true if grep returns anything"
- Mike Lyonspsql -l | grep '^ exact_dbname\b'
,如果未找到,则设置退出代码。 - Steve Bennett我刚接触postgresql,但以下命令是我用来检查数据库是否存在的
if psql ${DB_NAME} -c '\q' 2>&1; then
echo "database ${DB_NAME} exists"
fi
psql ${DB_NAME} -c ''
。 - Pedro Romano您可以使用以下方法创建数据库(如果它尚不存在):
if [[ -z `psql -Atqc '\list mydatabase' postgres` ]]; then createdb mydatabase; fi
我将其他答案结合起来,形成简洁且符合POSIX标准的形式:
psql -lqtA | grep -q "^$DB_NAME|"
返回true
(0
)表示它存在。
如果你怀疑你的数据库名称可能包含非标准字符,例如$
,你需要稍微长一点的方法:
psql -lqtA | cut -d\| -f1 | grep -qxF "$DB_NAME"
-t
和 -A
选项确保输出是原始的,而不是"表格"或空格填充的输出。列由管道字符 |
分隔,因此要么 cut
要么 grep
必须识别这个字符。第一列包含数据库名称。#!/bin/sh
DB_NAME=hahahahahahaha
psql -U postgres ${DB_NAME} --command="SELECT version();" >/dev/null 2>&1
RESULT=$?
echo DATABASE=${DB_NAME} RESULT=${RESULT}
#
为了完整起见,以下是使用正则表达式而不是字符串截取的另一种版本:
psql -l | grep '^ exact_dbname\b'
if psql -l | grep '^ mydatabase\b' > /dev/null ; then
echo "Database exists already."
exit
fi
\b
具有与所有使用grep -w
的答案相同的问题,即数据库名称可能包含非单词成分字符,例如-
,因此尝试匹配foo
也会匹配foo-bar
。 - philsPGCONNECT_TIMEOUT=3 psql development -h db -U postgres -c ""
bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:setup
psql -l | awk '{print $1}' | grep -w <database>
缩短版
... | grep 0
,如果数据库不存在,则使shell返回值为0,如果存在则返回1;或者使用... | grep 1
来实现相反的行为。 - acjaywc
。请看我的修改。(如果你想要反转退出状态,Bash 支持一个感叹号操作符:! psql ...
) - beneschwc
命令外,我会使用grep -qw <term>
。这将导致Shell在匹配成功时返回0
,否则返回1
。然后,$?
将包含返回值,您可以使用它来决定下一步该做什么。因此,我建议在这种情况下不要使用wc
。grep
将满足您的需求。 - Matt Friedman