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

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.

Leave a Comment