我想将实时数据从 psql 传输到另一个命令中,以便通过 shell 进行监控。
这可以做到吗?
到目前为止我有以下内容:
$ psql bareos -c '\watch (SELECT * FROM log ORDER BY time DESC LIMIT 200) TO STDOUT WITH CSV'
我正在使用 postgres 11.12。
但是当我运行命令时,我最终得到了错误:
\watch cannot be used with an empty query
然而,如果我直接从 psql 运行它,它完全能够观看实时输出。
我的目标是实现 Unix 风格的输出拖尾。
答案1
我尝试了几种变体,-c
但无法使其工作。看起来要么是我没有尝试足够的变化,要么\watch
就是无法使用psql -c
.
然后我尝试使用psql -f
(从文件中读取sql脚本)并且流程替代提供sql脚本“文件”,它工作得很好。
例如:
psql --csv -f <(printf '%s\n' \
'SELECT * FROM log ORDER BY time DESC LIMIT 200;' \
'\watch')
或者,如果您psql
不支持该--csv
选项:
psql -f <(printf '%s\n' \
'\pset format csv' \
'SELECT * FROM log ORDER BY time DESC LIMIT 200;' \
'\watch')
这printf
发送二sql 命令发送到psql
(先是select
,然后是\watch
),并用换行符 ( \n
) 分隔。这些命令中的每一个都必须单独用单引号引起来,以便它们是printf
.
请注意,SQL 在许多命令中也使用单引号,因此如果您需要运行使用单引号的 SQL 命令,则必须非常小心地引用命令的方式。例如
psql -f <(printf '%s\n' "select * from table where name='cas'" '\watch 5')
在此示例中,我在第一个 SQL 命令中使用双引号以避免带引号的字符串出现任何问题'cas'
。问题是 shell 中的双引号允许变量插值,因此如果您想要文字字符串而不是变量的值,则需要转义任何 shell 变量名称(例如,\$var
而不只是)。$var
例如
psql -f <(printf '%s\n' \
"select * from table where pass='\$1\$QsHP.S0S\$1Npjv4aKJZv4IjDD.PgNp/'" \
'\watch 5')
请注意,我必须使用$
a对每次出现的情况进行转义\
,以防止 shell 扩展字符串中看起来像变量名的部分。