替代 postgres 中用于脚本的 list 命令
Posted
技术标签:
【中文标题】替代 postgres 中用于脚本的 list 命令【英文标题】:Alternative to list command in postgres for scripting 【发布时间】:2014-02-11 02:45:31 【问题描述】:不幸的是 psql -l
使用换行
示例 查看输出并考虑“访问”列
数据库列表 姓名 |所有者 |编码 |整理 |类型 |访问权限 -------------------------+------------+----------+ -------------+-------------+---------- - 第一数据库 |后勤 | UTF8 | de_DE.UTF-8 | de_DE.UTF-8 | 数据库 | scnduser | UTF8 | de_DE.UTF-8 | de_DE.UTF-8 | 数据库 | scnduser | UTF8 | de_DE.UTF-8 | de_DE.UTF-8 | 后勤 |后勤 | UTF8 | de_DE.UTF-8 | de_DE.UTF-8 | 模板0 |后勤 | UTF8 | de_DE.UTF-8 | de_DE.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres 模板1 |后勤 | UTF8 | de_DE.UTF-8 | de_DE.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres (6 行)
提示即使有一些选项,我也无法摆脱它:
$ psql -Atlqn firstdb|postgres|UTF8|de_DE.UTF-8|de_DE.UTF-8| secnddb|scnduser|UTF8|de_DE.UTF-8|de_DE.UTF-8| thrddb|scnduser|UTF8|de_DE.UTF-8|de_DE.UTF-8| postgres|postgres|UTF8|de_DE.UTF-8|de_DE.UTF-8| 模板0|postgres|UTF8|de_DE.UTF-8|de_DE.UTF-8|=c/postgres postgres=CTc/postgres 模板1|postgres|UTF8|de_DE.UTF-8|de_DE.UTF-8|=c/postgres postgres=CTc/postgres
问题有没有另一种方法来获取数据库列表,就像\list
打印它一样,所以我可以在脚本中使用它来解析,例如怎么了?
【问题讨论】:
【参考方案1】:有趣的问题。您被 ACL 条目中的硬换行符咬住了。顺便说一句,它们并不是唯一可以出现的地方,只是最常见的地方。
使用空字节记录
与其避免使用换行符,不如使用不同的记录分隔符?一个空字节(\0
)可能是好的;这就是-0
选项的用途。但是,仅当您的客户端可以处理空字节时,它才有用;适合xargs -0
,不适合很多其他东西。空字节的方便之处在于它不会出现在psql
的输出中,否则不会有冲突的风险。 gawk
确实支持以空值分隔的记录,尽管它的文档记录严重不足。
试试,例如:
psql -Atlqn -0 | gawk -vRS=$'\0' ' gsub("\n", " "); print
用空格替换数据库名称中的换行符(是的,它们可以出现在那里!)、ACL 条目等。
使用不同的记录
或者,使用-R
,例如-R '!'
或 -R '--SEPARATOR--'
或任何易于解析且不太可能出现在输出中的内容。
自己查询目录,转义字符串
根据您需要的信息,您也可以直接查询目录或information_schema
。您仍然需要处理有趣的字符,因此您可能需要一个正则表达式来逃避任何有趣的事情。
换行符和 shell 元字符
请注意,您仍然需要处理意外的换行符;考虑当一些@#$@ 这样做时会发生什么:
CREATE DATABASE "my
database";
是的,这是一个合法的数据库名称。两者也是:
CREATE DATABASE "$(rm -rf /gladthisisnotroot);";
CREATE DATABASE "$(createuser -l -s my_haxxor -W top_secret)"
是的,两者都是合法的数据库名称。是的,如果你没有正确地转义你的 shell 元字符,你错误地以 root 或postgres
用户运行你的 shell 脚本,那真的非常糟糕,而且他们感觉不好。
【讨论】:
psql 9.1.1 似乎不支持 -0 它从 9.2+ postgresql.org/docs/9.2/static/app-psql.html 开始支持,但是谢谢,是的,这可行:psql -Atlqn -F\| -R'~~SEP~~' | awk 'BEGIN FS="|"; RS="~~SEP~~"; print "nl:"$0 '
跨度>
【参考方案2】:
所有相关数据都在pg_database
和pg_user
见http://www.postgresql.org/docs/current/static/catalog-pg-database.html
select pg_database.datname,pg_user.usename,pg_encoding_to_char(pg_database.encoding),pg_database.datcollate,pg_database.datctype,pg_database.datacl from pg_database,pg_user WHERE pg_database.datdba = pg_user.usesysid;
在 shell 上,包裹在 psql 命令中:
psql -AStnq -c "select [...]"
返回正确的格式
模板1|postgres|UTF8|de_DE.UTF-8|de_DE.UTF-8|=c/postgres,postgres=CTc/postgres 模板0|postgres|UTF8|de_DE.UTF-8|de_DE.UTF-8|=c/postgres,postgres=CTc/postgres postgres|postgres|UTF8|de_DE.UTF-8|de_DE.UTF-8| firstdb|postgres|UTF8|de_DE.UTF-8|de_DE.UTF-8| secnddb|scnduser|UTF8|de_DE.UTF-8|de_DE.UTF-8| thrddb|scnduser|UTF8|de_DE.UTF-8|de_DE.UTF-8|【讨论】:
这不会保护您免受datname
中的换行符(或更糟)的影响。以上是关于替代 postgres 中用于脚本的 list 命令的主要内容,如果未能解决你的问题,请参考以下文章
postgres 中 SET XACT_ABORT ON 的替代方法是啥
在 Postgres 中存储大量 JSON 数据是不可行的,那么有啥替代方案呢?
sql 用于处理创建Postgres数据库的脚本:```PG :: InvalidParameterValue:ERROR:编码UTF8不是