简体   繁体   English

Python 子进程挂起 psql 命令

[英]Python subprocess hangs with psql command

I am running the following piece of python code (runs a command in a shell and grabs its output or reports an error)我正在运行以下 Python 代码(在 shell 中运行命令并获取其输出或报告错误)

import sys
import subprocess
def check_output(args, communicate=None, quiet=False, **kwargs):
    for stream in ["stdout", "stderr"]:
        kwargs.setdefault(stream, subprocess.PIPE)

    proc = subprocess.Popen(args, **kwargs)
    try:
        out, err = proc.communicate()
    finally:
        for f in (proc.stdout, proc.stderr):
            if f is not None:
                f.close()
        proc.wait()

    if kwargs["stderr"] != subprocess.PIPE:
        err = ""

    if proc.returncode != 0:
        raise Exception(args, proc.returncode, err)
    else:
        if not quiet:
            sys.stderr.write(err)
            sys.stderr.flush()
    return out

with the following arguments:具有以下参数:

env = dict(
        PGHOST='{pg_host}',
        PGPORT='{pg_port}',
        PGDATABASE='{pg_dbname}',
        PGUSER='{pg_user}',
        PGPASSWORD='{pg_password}',
      )

cmd = ['psql', '-c', "INSERT INTO {ft_geom} SELECT * FROM {ft_geom_in};"].format(**tables)
check_output(cmd, shell=True, env=env)

Here env simply contains the PG[HOST|USER|DATABASE|PORT|..] environment variables and tables contains just the names of those 2 tables.这里env只包含PG[HOST|USER|DATABASE|PORT|..]环境变量, tables只包含这两个表的名称。 When I run this code, it hangs indefinitely on proc = subprocess.Popen call.当我运行这段代码时,它无限期地挂在proc = subprocess.Popen调用上。 I am using python 2.6.5 on Ubuntu 10.04.3 LTS我在Ubuntu 10.04.3 LTS上使用 python 2.6.5

I check that no tables are locked with the following:我检查没有表被以下锁定:

SELECT a.datname,
         c.relname,
         l.transactionid,
         l.mode,
         l.granted,
         a.usename,
         a.current_query, 
         a.query_start,
         age(now(), a.query_start) AS "age", 
         a.procpid 
    FROM  pg_stat_activity a
     JOIN pg_locks         l ON l.pid = a.procpid
     JOIN pg_class         c ON c.oid = l.relation
    ORDER BY a.query_start;

And it shows that all the locks were granted.它表明所有的锁都被授予了。 Not sure where else to look at.不知道还有什么地方可以看。 I need shell=True because the commands are sometimes more complex, requiring bash pipes.我需要shell=True因为命令有时更复杂,需要 bash 管道。 I know I should ideally pass stdout.PIPE of one command to the other, but its not possible to change this at the moment.我知道我应该理想地将一个命令的stdout.PIPE传递stdout.PIPE另一个命令,但目前无法改变这一点。

Running the very same command from bash directly works as expected, also, running without shell=True works从 bash 直接运行相同的命令可以按预期工作,而且,在没有shell=True情况下运行也可以

The problem was that I didn't filter newline characters in tokens passed to check_output , then shell would hang waiting for more input.问题是我没有过滤传递给check_output令牌中的check_output ,然后 shell 会挂起等待更多输入。 So make sure you escape the tokens when you pass them to shell.因此,请确保在将令牌传递给 shell 时对其进行转义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM