如何在Python中从没有结束的管道中读取stdin

34 投票
5 回答
72440 浏览
提问于 2025-04-16 23:46

我在用Python从标准输入或管道读取数据时遇到问题,特别是当管道来自一个“打开”的文件时(我不知道这个名字对不对)。

我有一个例子,叫pipetest.py:

import sys
import time
k = 0
try:
   for line in sys.stdin:
      k = k + 1
      print line
except KeyboardInterrupt:
   sys.stdout.flush()
   pass
print k

我运行一个程序,它会不断输出内容,然后过一会儿我按Ctrl+c停止它。

$ ping 127.0.0.1 | python pipetest.py
^C0

结果我没有任何输出。不过如果我用普通文件来做,就能正常工作。

$ ping 127.0.0.1 > testfile.txt

这个程序在短时间后也会被Ctrl+c结束。

$ cat testfile.txt |  python pipetest.py

PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.017 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.015 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.014 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.013 ms
64 bytes from 127.0.0.1: icmp_seq=5 ttl=64 time=0.012 ms

--- 127.0.0.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 3998ms
rtt min/avg/max/mdev = 0.012/0.014/0.017/0.003 ms
10

我该怎么做才能在程序结束之前获取一些输出,比如在这个例子中,ping命令已经结束了?

5 个回答

9

这个代码块是用来展示某些编程内容的。具体来说,它可能包含了一些示例代码或者是特定的编程语法。对于刚开始学习编程的人来说,理解这些代码的作用和结构是非常重要的。

在学习编程时,遇到代码块是很常见的事情。代码块通常用来展示一个完整的功能或者是一个特定的操作。你可以把它想象成一个食谱,里面详细列出了做某道菜所需要的材料和步骤。

如果你看到这样的代码块,不要害怕,慢慢分析每一行,试着理解它们是如何工作的。这样,你会逐渐掌握编程的基本概念和技巧。

k = 0
try:
    while True:
        print sys.stdin.readline()
        k += 1
except KeyboardInterrupt:
    sys.stdout.flush()
    pass
print k
16

为了让这个功能在不等到输入流结束的情况下工作,你可以使用 readline 来逐行读取。我觉得这是最简单的解决办法。

import sys
k = 0
try:
   for line in iter(sys.stdin.readline, b''):
      k = k + 1
      print line
except KeyboardInterrupt:
   sys.stdout.flush()
   pass
print k
38

试试这个:

import sys
import time
k = 0
try:
    buff = ''
    while True:
        buff += sys.stdin.read(1)
        if buff.endswith('\n'):
            print buff[:-1]
            buff = ''
            k = k + 1
except KeyboardInterrupt:
   sys.stdout.flush()
   pass
print k

撰写回答