我正在为程序编写一个包装脚本,该程序可选地接受stdin的输入。我的脚本需要处理文件的每一行,但还需要将stdin转发到它正在包装的程序中。以极简主义的形式,这看起来像这样:
import subprocess
import sys
for line in sys.stdin:
# Do something with each line
pass
subprocess.call(['cat'])
请注意,我实际上并不是要包装cat
,它只是一个例子来证明stdin是否正确地转发了。
在上面的示例中,如果我评论循环,则可以正常工作。但是,如果我用循环运行它,那么我已经读到了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