1

I'm running the following script with Python 3:

import sys, subprocess

line = sys.stdin.readline()
print(f'[p] {line}', end='')
subprocess.run('read one; echo "[s] $one"', shell=True)
line = sys.stdin.readline()
print(f'[p] {line}', end='')

If I run this script normally, this happens, as I expected:

a
[p] a
b
[s] b
c
[p] c

(I've typed three lines, with a single letter on each). However, if I create a text file containing these three lines, and run it using python3 script.py < file.txt, I get the following output:

[p] a
[s]
[p] b

When I expect to get

[p] a
[s] b
[p] c

I'm fairly sure this is due to an stdin buffering issue. I've tried (to no avail) setting PYTHONUNBUFFERED, and running Python with -u. Can I disable stdin buffering? Or can I access the contents of the buffer to pass them to my shell command?

Thanks!

1 Answer 1

1

It is a buffering issue, and I think this statement from the documentation of the io module is relevant:

"TextIOWrapper, which extends it [talking about TextIOBase], is a buffered text interface to a buffered raw stream"

The type of sys.stdin is TextIOWrapper, so it seems the buffering can't be got rid of using just sys.stdin.

However, it seems you can do this:

import io
f = io.FileIO(sys.stdin.fileno())

and then do f.readline(), independent of whether you specify -u or not.

The question remains whether this is a good idea at all. I think an implementation which relies so critically on exactly how much is buffered is very unreliable.

Sign up to request clarification or add additional context in comments.

1 Comment

You seem to run at least python 3.5. I tried with python 2, and there, -u with your code did make a difference.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.