我被困在管道输出一个脚本到另一个脚本(两个都是python)。在
这个question非常相似,但是(1)它没有提供答案(2)我的有点不同。所以,我觉得开一个新的问题会更好。在
问题就在这里。
两个脚本几乎相同:
接收器.py
import sys
import time
for line in sys.stdin:
sys.stdout.write(line)
sys.stdout.flush()
time.sleep(3)
复制器.py
^{pr2}$当我在bash或cmd中逐个执行这些脚本时,一切都很好。下面两个例子都在工作,我在输出中看到了输入文本:
工作:(每3秒出现一行输出)
cat data.txt | python receiver.py
cat data.txt | python replicator.py
但是一旦我从一个脚本管道到另一个脚本,它们就会停止工作:
不起作用:(在到达文件结尾之前不会显示任何内容)
cat data.txt | python receiver.py | python replicator.py
然后,当我把第一个脚本管道到另一个工具时,它又起作用了!在
作品:
cat data.txt | python receiver.py | cat -n
cat data.txt | python replicator.py | cat -n
最后,当我删除blocking sleep()函数时,它又开始工作了:
删除计时器:
time.sleep(0)
现在它起作用了:
cat data.txt | python receiver.py | python replicator.py
有人知道我的烟斗怎么了吗? 我不是在寻找其他的方法。我只想知道这里发生了什么。在
根据评论,我改进了示例。
现在,这两个脚本不仅打印出data.txt
的内容,而且还在每一行添加一个时间戳。在
接收器.py
import sys
import time
import datetime
for line in sys.stdin:
sys.stdout.write(str(datetime.datetime.now().strftime("%H:%M:%S"))+'\t')
sys.stdout.write(line)
sys.stdout.flush()
time.sleep(1)
数据.txt
Line-A
Line-B
Line-C
Line-D
结果
$> cat data.txt
Line-A
Line-B
Line-C
Line-D
$> cat data.txt | python receiver.py
09:05:44 Line-A
09:05:45 Line-B
09:05:46 Line-C
09:05:47 Line-D
$> cat data.txt | python receiver.py | python receiver.py
09:05:54 09:05:50 Line-A
09:05:55 09:05:51 Line-B
09:05:56 09:05:52 Line-C
09:05:57 09:05:53 Line-D
$> cat test.log | python receiver.py | sed -e "s/^/$(date +"%H:%M:%S") /"
09:17:55 09:17:55 Line-A
09:17:55 09:17:56 Line-B
09:17:55 09:17:57 Line-C
09:17:55 09:17:58 Line-D
$> cat test.log | python receiver.py | cat | python receiver.py
09:36:21 09:36:17 Line-A
09:36:22 09:36:18 Line-B
09:36:23 09:36:19 Line-C
09:36:24 09:36:20 Line-D
正如您看到的,当我将python脚本的输出管道到它自己时,第二个脚本会一直等到第一个脚本完成。然后它开始消化数据。在
但是,当我使用另一个工具(在本例中为sed
)时,该工具会立即接收数据。为什么会这样?在
这是由于文件对象中的内部缓冲区(
for line in sys.stdin
)的缘故。在所以,如果我们一行一行地提取:
代码将按预期工作:
^{2}$Documentation
注意:在Python 3中,
File Object
的事情被修复了相关问题 更多 >
编程相关推荐