python脚本之间的管道 [英] Pipe between python scripts
问题描述
我有一个简单的脚本,该脚本从设备读取值并通过 print
输出它们,还有另一个脚本,该脚本侦听stdin并解释每个数字.设备每秒输出一个数字.令人惊讶的是,在我的ubuntu框上传递脚本不起作用.但是,如果使第一个脚本不从设备读取,而是尽可能快地生成随机数,则第二个脚本将成功接收数据.
I have a simple script that reads values from a device and outputs them via print
, and another script, which listens on stdin and interprets each number. The device outputs one number each second. Surprisingly, piping the scripts on my ubuntu box does not work. However, if the first script is made not to read from the device but generate random numbers as fast as it can, the second script successfully receives the data.
下面是我的情况的简化示例.
Below is a simplified example of my situation.
print.py:
#!/usr/bin/env python2
import time
import sys
while True:
time.sleep(1) # without this everything works
print "42"
sys.stdout.flush()
read.py:
#!/usr/bin/env python2
import sys
while True:
for str in sys.stdin:
print str
命令行调用:
vorac@laptop:~/test$ ./print.py | ./read.py
这是最终结果.第一个脚本从设备读取数据,第二个脚本在两个单独的时间范围(显示为随机数)中绘制数据图表.
Here is the end result. The first script reads from the device and the second graphs the data in two separate time frames (what is shown are random numbers).
推荐答案
嗯,现在这是一个棘手的问题.发生这种情况是因为 sys.stdin
的迭代器方法(即 Python会尝试从真实的引擎盖下标准输入流中读取,直到其内部缓冲区已满,并且只有在缓冲区已满时才进行读取通过循环的主体.缓冲区大小为8 KB ,因此需要一个一会儿.
Ah, now that is a tricky problem. It happens because the iterator method for sys.stdin
(which is xreadlines()
) is buffered. In other words, when your loop implicitly calls next(sys.stdin)
to get the next line of input, Python tries to read from the real under-the-hood standard input stream until its internal buffer is full, and only once the buffer is full does it proceed through the body of the loop. The buffer size is 8 kilobytes, so this takes a while.
您可以通过将 sleep()
调用中的时间延迟减少到 0.001
或一些这样的值来查看此情况,具体取决于系统的功能.如果您恰好赶上了时间,那么几秒钟内您什么都看不到,然后立刻弹出整个 42
块.
You can see this by decreasing the time delay in the sleep()
call to 0.001
or some such value, depending on the capabilities of your system. If you hit the time just right, you'll see nothing for a few seconds, and then a whole block of 42
s come out all at once.
要修复此问题,请使用 sys.stdin.readline()
,它是无缓冲的.
To fix it, use sys.stdin.readline()
, which is unbuffered.
while True:
line = sys.stdin.readline()
print line
您可能还希望在打印后去除尾随的换行符,否则会出现双换行符.使用 line.rstrip('\ n')
或仅使用 print line
来抑制多余的换行符.
You might also want to strip off the trailing newline before printing it, otherwise you'll get double line breaks. Use line.rstrip('\n')
, or just print line,
to suppress the extra newline that gets printed.
这篇关于python脚本之间的管道的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!