简体   繁体   English

从stdin读取并将其转发到Python中的子进程

[英]Read from stdin AND forward it to a subprocess in Python

I'm writing a wrapper script for a program that optionally accepts input from STDIN. 我正在为一个程序编写一个包装脚本,该脚本可选择接受来自STDIN的输入。 My script needs to process each line of the file, but it also needs to forward STDIN to the program it is wrapping. 我的脚本需要处理文件的每一行,但它还需要将STDIN转发到它正在包装的程序。 In minimalist form, this looks something like this: 在极简主义的形式,这看起来像这样:

import subprocess
import sys

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

subprocess.call(['cat'])

Note that I'm not actually trying to wrap cat , it just serves as an example to demonstrate whether or not STDIN is being forwarded properly. 请注意,我实际上并没有尝试包装cat ,它只是作为一个示例来演示是否正确转发STDIN。

With the example above, if I comment out the for-loop, it works properly. 通过上面的例子,如果我注释掉for循环,它就可以正常工作。 But if I run it with the for-loop, nothing gets forwarded because I've already read to the end of STDIN. 但是,如果我使用for循环运行它,则没有任何内容被转发,因为我已经读到了STDIN的末尾。 I can't seek(0) to the start of the file because you can't seek on streams. 我不能seek(0)到文件的开头,因为你不能在流上寻找。

One possible solution is to read the entire file into memory: 一种可能的解决方案是将整个文件读入内存:

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))

which works, but isn't very memory efficient. 哪个有效,但效率不高。 Can anyone think of a better solution? 谁能想到更好的解决方案? Perhaps a way to split or copy the stream? 也许是分割或复制流的方法?

Additional Constraints: 附加限制:

  1. The subprocess can only be called once. 子进程只能调用一次。 So I can't read a line at a time, process it, and forward it to the subprocess. 因此,我不能一次读取一行,处理它,并将其转发到子流程。
  2. The solution must work in Python 2.6 该解决方案必须在Python 2.6中运行

Does this work for you? 这对你有用吗?

#!/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)

Example: 例:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM