2016-12-02 74 views
0

我正在为可选接受来自STDIN的输入的程序编写包装脚本。我的脚本需要处理文件的每一行,但它也需要将STDIN转发到它正在打包的程序。在简约的形式,这看起来是这样的:从stdin读取并将其转发到Python中的子进程

import subprocess 
import sys 

for line in sys.stdin: 
    # Do something with each line 
    pass 

subprocess.call(['cat']) 

请注意,我没有真正试图总结cat,而只是作为一个例子来说明是否STDIN被正确转发。

用上面的例子,如果我注释掉for循环,它可以正常工作。但是如果我用for循环运行它,没有任何东西会被转发,因为我已经阅读了STDIN的结尾。我不能seek(0)到文件的开始,因为你不能在流上寻找。

一个可能的解决方案是将整个文件读入内存:

import subprocess 
import sys 

lines = sys.stdin.readlines() 
for line in lines: 
    # Do something with each line 
    pass 

p = subprocess.Popen(['cat'], stdin=subprocess.PIPE) 
p.communicate(''.join(lines)) 

其作品,但不是很高效利用内存。任何人都可以想出更好的解决方案吗也许一种分割或复制流的方法?

附加约束:

  1. 子进程只能被调用一次。所以我不能一次读一行,处理它,并将它转发给子进程。
  2. 解决方案必须在Python 2.6
+0

如果我理解正确的这个,你想从'stdin'基本数据转发给子进程的'stdin'? – bkvaluemeal

+0

是的,但如果我只想把'stdin'转发给子进程,'subprocess.call(['cat'])'将是我所需要的。我想转发'stdin'并且能够读取和处理它。 –

回答

0

不工作这对你的工作?

#!/usr/bin/env python2 
import subprocess 
import sys 

p = subprocess.Popen(['cat'], stdin = subprocess.PIPE) 

line = sys.stdin.readline() 

#################### 
# Insert work here # 
#################### 

line = line.upper() 

#################### 

p.communicate(line) 

例子:

$ echo "hello world" | ./wrapper.py 
HELLO WORLD 
+0

该解决方案有两个问题: 1.它只转发标准输入的第一行,而不是每行。您需要使用'readlines'(复数),并在将它们传递给子进程时加入它们。 2.这是我已经提出的同样的解决方案,混乱了一下。它具有将整个文件读入内存的缺陷。我正在寻找更高效的内存解决方案(如果存在的话)。 –

+0

在这里大声思考。如果子进程之后的代码在while循环内连续读取一行,处理它然后进行通信呢?这不是一种类似于您所寻找的类似流式的方法吗? – bkvaluemeal

+0

请参阅其他约束条件:#1。 –