如何将一个python脚本的输出管道到另一个python脚本

2024-04-25 13:54:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我被困在管道输出一个脚本到另一个脚本(两个都是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}$

当我在bashcmd中逐个执行这些脚本时,一切都很好。下面两个例子都在工作,我在输出中看到了输入文本:

工作:(每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)时,该工具会立即接收数据。为什么会这样?在


Tags: pyimporttxt脚本data管道timestdout
1条回答
网友
1楼 · 发布于 2024-04-25 13:54:07

这是由于文件对象中的内部缓冲区for line in sys.stdin)的缘故。在

所以,如果我们一行一行地提取

import sys
import time
import datetime

while True:
    line = sys.stdin.readline()
    if not line:
       break
    sys.stdout.write(str(datetime.datetime.now().strftime("%H:%M:%S"))+'\t')
    sys.stdout.write(line)
    sys.stdout.flush()
    time.sleep(1)

代码将按预期工作:

^{2}$

Documentation

... Note that there is internal buffering in file.readlines() and File Objects (for line in sys.stdin) which is not influenced by this option. To work around this, you will want to use file.readline() inside a while 1: loop.

注意:在Python 3中,File Object的事情被修复了

相关问题 更多 >