从stdin读取并将其转发到Python中的子进程
我正在为可选接受来自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))
其作品,但不是很高效利用内存。任何人都可以想出更好的解决方案吗也许一种分割或复制流的方法?
附加约束:
- 子进程只能被调用一次。所以我不能一次读一行,处理它,并将它转发给子进程。
- 解决方案必须在Python 2.6
不工作这对你的工作?
#!/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
该解决方案有两个问题: 1.它只转发标准输入的第一行,而不是每行。您需要使用'readlines'(复数),并在将它们传递给子进程时加入它们。 2.这是我已经提出的同样的解决方案,混乱了一下。它具有将整个文件读入内存的缺陷。我正在寻找更高效的内存解决方案(如果存在的话)。 –
在这里大声思考。如果子进程之后的代码在while循环内连续读取一行,处理它然后进行通信呢?这不是一种类似于您所寻找的类似流式的方法吗? – bkvaluemeal
请参阅其他约束条件:#1。 –
如果我理解正确的这个,你想从'stdin'基本数据转发给子进程的'stdin'? – bkvaluemeal
是的,但如果我只想把'stdin'转发给子进程,'subprocess.call(['cat'])'将是我所需要的。我想转发'stdin'并且能够读取和处理它。 –