如何使用popen将stdout传递给另一个程序?

时间:2014-04-13 21:37:16

标签: python subprocess

如果以前曾经问过这个问题,我会道歉,我已经搜索过一堆并且没有找到答案。

我有一系列系统调用,我正在编写一个脚本,其中一个是以下形式:

cat file | /some/program o > output.txt

本质上,将文件输出到标准输出,然后通过管道输出到某个程序,然后在程序上运行并将输出放到其他文件中。在这种情况下,/ some / program的使用非常不灵活,我必须将文件写入其中并使用参数o> some_out_file以便使用它。

将该行的shlex.split()传递给popen()的args只打印文件,/ some / program的二进制文件和output.txt(如果存在),这显然不是我所知道的寻找。

我一般都很擅长使用p​​ython的这一部分,如果答案很明显,如果有其他方式进行系统调用而不是尝试使用subprocess.popen( )或类似的我也对此持开放态度,任何帮助都表示赞赏!

或者我可以为此调用os.system(...)但是为了保持与本脚本其余部分的一致性,我宁愿在这种情况下不使用特定的异常。

2 个答案:

答案 0 :(得分:0)

这是你在找什么?

Popen.communicate

  

与流程交互:将数据发送到stdin。从stdout和stderr读取数据,直到达到文件结尾。等待进程终止。可选的输入参数应该是要发送到子进程的字符串,如果没有数据应该发送给子进程,则为None。

这与调用cat file | head -n 10 > out.txt

类似
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import subprocess

program="head"
args=["-n", "10"]
popen_args = [program] + args #["head", "-n", "10"]

p = subprocess.Popen(popen_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# sample stdin
stdin = "\n".join(["line %s" % x for x in xrange(0, 100)])
out, err = p.communicate(stdin)

# save to file
with open('out.txt', 'w') as f: f.write(out)

答案 1 :(得分:0)

在Python中模拟< file /some/program o > output.txt shell命令:

from subprocess import check_call

with open('file', 'rb', 0) as file, open('output.txt', 'wb', 0) as output_file:
    check_call(['/some/program', 'o'], stdin=file, stdout=output_file)

要回答标题中的问题,您可以使用"Replacing shell pipeline" example from the docs

from subprocess import Popen, PIPE

# cat file | /some/program o > output.txt
p1 = Popen(["cat", "file"], stdout=PIPE)
with open('output.txt', 'wb', 0) as output_file:
    p2 = Popen(["/some/program", "o"], stdin=p1.stdout, stdout=output_file)
p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.
p1.wait()
p2.wait()

如果shell命令来自可信输入,您可以使用shell=True创建管道:

check_call("/bin/a b c | /bin/d 'e f'", shell=True)