如何从shell脚本中的postgresql中取代pg_backend_pid并将其传递给另一个进程?

jes*_*ess 3 postgresql shell perl

我需要bin/psql在命令行(或脚本)上运行并打印pg_backend_pid出来,以便pg_backend_pid可以将其作为命令行参数传递给另一个进程(由root运行).对我来说问题是其他进程需要在获得pid后运行.然后psql(使用相同的pid会话)在另一个进程启动后运行查询.

诀窍是Psql需要等到其他进程获得pg_backend_pid并且它必须保持相同的会话.

可以通过shell脚本或perl来完成吗?

Cra*_*ger 10

你会想要在bash中使用协同进程,或者在perl中使用某种双向管道.在Python中,您可以使用os.popen2命令; perl还具有通过管道与子进程交互的工具.然而,这是很多更好地使用本地语言数据库驱动程序一样DBD::Pgpsycopg2在所有可能的如果.

如果必须在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}"
Run Code Online (Sandbox Code Playgroud)

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()
Run Code Online (Sandbox Code Playgroud)

在Perl中,您可以使用DBI和DBD :: Pg来实现类似的效果.