How do you read from stdin in python from a pipe which has no ending

Janne picture Janne · Aug 17, 2011 · Viewed 51.5k times · Source

I've problem to read from Standard input or pipe in python when the pipe is from a "open" (do not know right name) file.

I have as example 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

I run a program that have continues output and Ctrl+c after a while

$ ping 127.0.0.1 | python pipetest.py
^C0

I get no output. But if I go via an ordinary file it works.

$ ping 127.0.0.1 > testfile.txt

this is ended by Ctrl+c after a short while

$ 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

How do I do to get any output before the program ends, in this case ping has ended?

Answer

Roman Bodnarchuk picture Roman Bodnarchuk · Aug 17, 2011

Try the next:

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