如何在shell脚本中从postgresql中提取pg_backend_pid并将其传递给另一个进程?
我需要在命令行(或脚本)上运行bin/psql
,并将其pg_backend_pid
输出,以便将pg_backend_pid
作为命令行parameter passing给另一个进程(由root运行)。 对我来说问题是,其他进程需要在获得pid后运行。 psql
(具有相同的pid会话)然后在另一个进程启动后运行查询。
诀窍是Psql需要等到其他进程获得pg_backend_pid
并且它必须保持相同的会话。
这可以通过shell脚本或Perl完成吗?
你会想在bash中使用一个协处理,或者在perl中使用某种双向pipe道。 在Python中,您可以使用os.popen2命令; perl还具有与pipe道上的subprocess交互的设施 。 但是,如果可能的话 ,使用本地语言数据库驱动程序(如DBD::Pg
或psycopg2
要好得多。
如果您必须在shell中执行此操作,请参阅“info bash”并search“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的参数是确保它不会暂停input,不会将制表符或元字符解释为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来实现类似的效果。