2011-10-30 28 views
3

我需要在命令行(或脚本)上运行bin/psql并打印它的pg_backend_pid,这样pg_backend_pid可以作为命令行参数传递给另一个进程(由root运行)。对我而言,问题在于其他进程需要在获得pid后运行。 psql(具有相同的pid会话)然后在另一个进程启动后运行查询。如何在shell脚本中从postgresql中提取pg_backend_pid并将其传递给另一个进程?

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

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

+0

你究竟在做什么? bin/psql与perl脚本有什么关系? – Flimzy

回答

9

你会想在bash中使用一个协处理器,或者在perl中使用某种双向管道。在Python中,您可以使用os.popen2命令; perl also has facilities for interacting with subprocesses over pipes。但是,如果可能的话,更适合使用本机语言数据库驱动程序,如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}" 

给psql的论据是,以确保它不会暂停输入,不解释选项卡或metachars作为readline的命令,不漂亮的打印输出,所以它更容易互动在壳。

或者,您可能根本不需要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来达到类似的效果。

+0

+1非常有趣的解决方案。 –

相关问题