Как извлечь pg_backend_pid из postgresql в сценарии оболочки и передать его другому процессу? - PullRequest
3 голосов
/ 30 октября 2011

Мне нужно запустить bin/psql в командной строке (или скрипте) и вывести его pg_backend_pid, чтобы pg_backend_pid мог быть передан другому процессу (от имени root) как аргумент командной строки.Проблема для меня в том, что другой процесс должен запускаться после получения pid.Затем psql (с таким же сеансом pid) запускает запрос после запуска другого процесса.

Хитрость в том, что Psql должен ждать, пока другой процесс не получит pg_backend_pid, и он должен остаться в том же сеансе.

Это можно сделать с помощью сценария оболочки или perl?

1 Ответ

10 голосов
/ 29 ноября 2011

Вы захотите использовать сопроцесс в bash или в perl с каким-то двусторонним каналом.В Python вы можете использовать команду os.popen2; Perl также имеет средства для взаимодействия с подпроцессами по каналам .Однако намного лучше использовать драйверы баз данных на родном языке, такие как DBD::Pg или psycopg2, если это вообще возможно.

Если вы должны сделать это в оболочке, см. "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 должны гарантировать, что он не останавливается для ввода, не делаетt интерпретирует табуляцию или метасхемы как команды 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 для достижения аналогичного эффекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...