我需要在命令行(或脚本)上运行bin/psql
并打印其pg_backend_pid
,以便pg_backend_pid
可以传递给另一个进程(由root运行)命令行参数。对我来说问题是其他进程需要在获得pid后运行。 psql
(具有相同的pid会话)然后在另一个进程启动后运行查询。
诀窍是Psql需要等到另一个进程获得pg_backend_pid
并且它必须保持相同的会话。
可以通过shell脚本或perl来完成吗?
答案 0 :(得分:10)
你想在bash中使用协同进程,或者在perl中使用某种双向管道。在Python中,您可以使用os.popen2命令; perl also has facilities for interacting with subprocesses over pipes。但是,如果可能的话,使用DBD::Pg
或psycopg2
等本地语言数据库驱动程序会更好 。
如果您必须在shell中执行此操作,请参阅“info bash”并搜索“coprocess”。
这是一个快速演示bash脚本,可以帮助您入门。
#!/bin/bash
set -e -u
DBNAME=whatever_my_db_is_called
coproc psql --quiet --no-align --no-readline --tuples-only -P footer=off --no-password "$DBNAME"
echo 'SELECT pg_backend_pid();' >&${COPROC[1]}
read -u ${COPROC[0]} backend_pid
echo "Backend PID is: ${backend_pid}"
echo "SELECT random();" >&${COPROC[1]}
read -u ${COPROC[0]} randnum
echo "\q" >&${COPROC[1]}
wait %1
echo "Random number ${randnum} generated by pg backend ${backend_pid}"
psql的参数是确保它不会暂停输入,不会将制表符或元搜索解释为readline命令,并且不会打印输出,因此它更容易在shell上进行交互。
或者,您可能根本不需要psql,只需通过某种脚本与PostgreSQL服务器通信即可。如果是这种情况,那么使用PostgreSQL数据库接口的脚本语言会更容易。在Python中,例如:
#!/usr/bin/env python
import os
import sys
import psycopg2
def main():
conn = psycopg2.connect("dbname=classads")
curs = conn.cursor()
curs.execute("SELECT pg_backend_pid();");
pid = curs.fetchall()[0][0]
# Do whatever you need to here,
# like using os.system() or os.popen() or os.popen2() to talk to
# system commands, using curs.execute() to talk to the database, etc.
conn.close();
if __name__ == '__main__':
main()
在Perl中,您可以使用DBI和DBD :: Pg来实现类似的效果。