我正在运行以下的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
使用以下参数:
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)
此处env
只包含PG[HOST|USER|DATABASE|PORT|..]
个环境变量,而tables
只包含这两个表的名称。当我运行此代码时,它会在proc = subprocess.Popen
调用时无限期挂起。我在2.6.5
Ubuntu 10.04.3 LTS
我检查没有表被锁定以下内容:
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;
它表明所有的锁都被授予了。不知道还能在哪里看。我需要shell=True
,因为命令有时更复杂,需要bash管道。我知道理想情况下我应该将stdout.PIPE
的一个命令传递给另一个命令,但目前无法改变这一点。
直接从bash运行相同的命令可以按预期工作,也可以在没有shell=True
的情况下运行
答案 0 :(得分:0)
问题是我没有过滤传递给check_output
的令牌中的换行符,然后shell会挂起等待更多输入。所以当你把它们传递给shell时,请确保你逃脱了它们。