4

I have these two scripts:

clock.py

#!/usr/bin/env python3
import time

while True: 
    print("True", flush=True)
    time.sleep(1)

continuous_wc.py

#!/usr/bin/env python3
import sys

def main():
    count = 0
    for line in sys.stdin:
        sys.stdout.write(str(count))
        count += 1

if __name__=='__main__':
    main()

And I run them like so:

./clock.py | ./continuous_wc.py

I'm hoping that it prints:

1
2
3
4
5
...

Every second is like a clock, because it's counting the lines in the file basically. But it doesn't output anything. Why not?

Ted Klein Bergman
  • 9,146
  • 4
  • 29
  • 50
BigBoy1337
  • 4,735
  • 16
  • 70
  • 138

2 Answers2

4

In addition to print(x, flush=True) you must also flush after sys.stdout.write.

Note that the programs would technically work without flush, but they would print values very infrequently, in very large chunks, as the Python IO buffer is many kilobytes. Flushing is there to make it work more real-time.

sys.stdout.write(str(count))
sys.stdout.flush()
Mike Clark
  • 10,027
  • 3
  • 40
  • 54
3

Using everyone's advice, this is what I have now (which works):

clock.py

#!/usr/bin/env python3
import time

while True:
    print("True", flush=True) 
    time.sleep(1)

continuous_wc.py

#!/usr/bin/env python3
import sys

def main():
    count = 0
    for line in sys.stdin:
        print(count, flush=True, end='\r')
        count += 1

if __name__=='__main__':
    main()

I had to use flush=True in both the write and the read scripts. However when using PYTHONUNBUFFERED=1, I was able to skip this and it worked. Thanks @Mark Setchell. Additionally, I am using print and stdin but it seems fileinput.input works as well.

Ted Klein Bergman
  • 9,146
  • 4
  • 29
  • 50
BigBoy1337
  • 4,735
  • 16
  • 70
  • 138