Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
680 views
in Technique[技术] by (71.8m points)

perl - How to extrace pg_backend_pid from postgresql in shell script and pass it to another process?

I need to run bin/psql on the command line (or script) and print its pg_backend_pid out, so that the pg_backend_pid can be passed to another process (run by root) as command line argument. The problem for me is that the other process needs to run after it obtains the pid. The psql (with same pid session) then runs a query after the other process has started.

The trick is that Psql needs to wait until the other process gets the pg_backend_pid and it has to remain the same session.

Can this be done through shell script or perl?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You'll want to use a coprocess in bash, or in perl with some kind of two-way pipe. In Python you can use the os.popen2 command; perl also has facilities for interacting with subprocesses over pipes. However, it's much better to use native language database drivers like DBD::Pg or psycopg2 if at all possible.

If you must do this in the shell, see "info bash" and search for "coprocess".

Here's a quick demo bash script to get you started.

#!/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}"

The arguments to psql are to ensure it doesn't pause for input, doesn't interpret tabs or metachars as readline commands, and doesn't pretty-print output so it's easier to interact with on the shell.

Alternately, it's possible you don't really need psql at all, you just need to talk to the PostgreSQL server via some kind of script. If that's the case, it'll be MUCH easier to just use a scripting language with a PostgreSQL database interface. In Python, for example:

#!/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()

In Perl you can use DBI and DBD::Pg to achieve a similar effect.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...