在python

时间:2018-04-22 09:28:27

标签: python python-2.7 shell command-line popen

我想在Python中调用一个复杂的命令行来捕获它的输出,我不明白我应该怎么做:

我尝试运行的命令行是:

cat codegen_query_output.json | jq -r '.[0].code' | echoprint-inverted-query index.bin

据我所知:

process = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE)
out, err = process.communicate()
print out

但这是一个简单的ls -a([cmd,args])任何想法我应该如何运行/构建我复杂的命令行调用?

2 个答案:

答案 0 :(得分:3)

最干净的方法是创建两个通过管道连接的子流程。您不需要cat命令的子进程,只需传递打开的文件句柄:

import subprocess

with open("codegen_query_output.json") as input_stream:
    jqp = subprocess.Popen(["jq","-r",'.[0].code'],stdin=input_stream,stdout=subprocess.PIPE)
    ep = subprocess.Popen(["echoprint-inverted-query","index.bin"],stdin=jqp.stdout,stdout=subprocess.PIPE)
    output = ep.stdout.read()
    return_code = ep.wait() or jqp.wait()

jqp进程将文件内容作为输入。其输出传递给ep输入。

最后,我们从ep读取输出以获得最终结果。 return_code是两个返回码的组合。如果出现问题,它与0不同(更详细的返回代码信息当然是单独测试)

此处不考虑标准错误。它将显示在控制台上,除非设置stderr=subprocess.STDOUT(与管道输出合并)

此方法不需要shell或shell=True,因此它更具便携性和安全性。

答案 1 :(得分:1)

需要shell来解释operators like |。您可以要求Python运行shell,并将命令作为要执行的命令传递:

cmd = "cat test.py | tail -n3"                                                  
process = subprocess.Popen(['bash', '-c', cmd], stdout=subprocess.PIPE)         
out, err = process.communicate()                                                
print out