• Flush the standard input with Ctrl+d
  • alternatively use input() or raw_input()
  • check the docs >>> help(sys.stdin.read)
Answer from Flint on Stack Overflow
🌐
Python
bugs.python.org › issue5505
Issue 5505: sys.stdin.read() doesn't return after first EOF on Windows - Python tracker
March 18, 2009 - This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/49755
Discussions

[baremetal] sys.stdin does not handle ctrl-D EOF markers
sys.stdin.read(), sys.stdin.readlines(), etc. do not handle ctrl-D at the beginning of a line as EOF (except on ports like unix). So for instance, there's no way to terminate input when doing s... More on github.com
🌐 github.com
4
October 7, 2017
python - What does sys.stdin read? - Stack Overflow
According to me sys.stdin.read() method accepts a line as the input from the user until a special character like Enter Key and followed by Ctrl + D and then stores the input as the string. Control + D works as the stop signal. More on stackoverflow.com
🌐 stackoverflow.com
sys.stdin.readline not working as expected
It’s confusing what you’re even trying to do. Everything works as expected, I’m confused what you’re expecting though. More on reddit.com
🌐 r/learnpython
7
1
July 1, 2018
python - sys.stdin.readline() reads without prompt, returning 'nothing in between' - Stack Overflow
It's not trivial, and it's different on Windows vs. everything else. There are actually three cases: a Unix tty, a Windows DOS prompt, or a regular file (redirected file/pipe) on either platform. And you have to handle them differently. First, to check if stdin is a tty (both Windows and Unix varieties), you just call sys.stdin.isatty(). That part is cross-platform. For the non-tty case, it's easy. It may actually just work... More on stackoverflow.com
🌐 stackoverflow.com
Top answer
1 of 2
15
Hi Brendan, in this video the "sys.stdin.read()" is described as being able to take a newline and finish your entry with Control+D. input() would finish your entry with the "Enter" key being pressed on your keyboard, so you couldn't include a newline in your data input that way.
2 of 2
6
That sounds roughly correct, however input() also takes as an argument a string to use as a prompt, while sys.stdin.read() takes the length to read into the user-entered string as an optional argument instead (and provides no prompt - in the video, a print() was provided to serve as a prompt instead). For more information on what these functions are doing though, you can use help(sys.stdin.read) and help(input) while in a Python interpreter, or visit https://docs.python.org/2/library/sys.html for more information about the sys library and its methods, including stdin. As for your other question, we have to import the sys library because sys.stdin.read() is reflecting a method that exists only in that library. The reason it's so long is that we just imported the library, so we have to reference sys at the beginning of any function from that library, then .stdin() is a function with a .read() method available in it (among others) - so it wouldn't make sense to just say read() without telling Python which read() method you're asking it to use (other functions, including one you write yourself, could include their own read() methods). If you mean to say why sys is a library instead of being ready for use in Python all the time, that's likely because it would be inefficient for Python to keep libraries loaded if they aren't being used, so the library is kept optional.
🌐
GitHub
github.com › micropython › micropython › issues › 3356
[baremetal] sys.stdin does not handle ctrl-D EOF markers · Issue #3356 · micropython/micropython
October 7, 2017 - sys.stdin.read(), sys.stdin.readlines(), etc. do not handle ctrl-D at the beginning of a line as EOF (except on ports like unix). So for instance, there's no way to terminate input when doing s...
Author   dhalbert
Top answer
1 of 6
49

So you have used Python's "pre built in functions", presumably like this:

file_object = open('filename')
for something in file_object:
    some stuff here

This reads the file by invoking an iterator on the file object which happens to return the next line from the file.

You could instead use:

file_object = open('filename')
lines = file_object.readlines()

which reads the lines from the current file position into a list.

Now, sys.stdin is just another file object, which happens to be opened by Python before your program starts. What you do with that file object is up to you, but it is not really any different to any other file object, its just that you don't need an open.

for something in sys.stdin:
    some stuff here

will iterate through standard input until end-of-file is reached. And so will this:

lines = sys.stdin.readlines()

Your first question is really about different ways of using a file object.

Second, where is it reading from? It is reading from file descriptor 0 (zero). On Windows it is file handle 0 (zero). File descriptor/handle 0 is connected to the console or tty by default, so in effect it is reading from the keyboard. However it can be redirected, often by a shell (like bash or cmd.exe) using syntax like this:

myprog.py < input_file.txt 

That alters file descriptor zero to read a file instead of the keyboard. On UNIX or Linux this uses the underlying call dup2(). Read your shell documentation for more information about redirection (or maybe man dup2 if you are brave).

2 of 6
8

It is reading from the standard input - and it should be provided by the keyboard in the form of stream data.

It is not required to provide a file, however you can use redirection to use a file as standard input.

In Python, the readlines() method reads the entire stream, and then splits it up at the newline character and creates a list of each line.

lines = sys.stdin.readlines()

The above creates a list called lines, where each element will be a line (as determined by the end of line character).

You can read more about this at the input and output section of the Python tutorial.

If you want to prompt the user for input, use the input() method (in Python 2, use raw_input()):

user_input = input('Please enter something: ')
print('You entered: {}'.format(user_input))
🌐
Reddit
reddit.com › r/learnpython › sys.stdin.readline not working as expected
r/learnpython on Reddit: sys.stdin.readline not working as expected
July 1, 2018 -

I working on a basic password generator and am running the following function to check the password length based on user input.

def passLength():
    len = sys.stdin.readline()
    try:
        len = int(len)
    except ValueError:
        print('    Must enter a number')
        len = None
        passLength()
    len = int(len)
    if len < 6:
        print('    Invalid Entry. Password must be at least 6 characters in length')
        passLength()
    else:
        return len

This works... unless the user types alphabetic characters prior to a number. Through debugging I found that "sys.stdin.readline" isn't adding new values to the "len" variable when the function is called multiple times.

You'll notice I'm clearing "len" by setting it to "None" I have also attempted to resolve it by setting "len" to an empty string with no success.

What can I do to either 1) fully reset my passLength function or 2) effectively clear previous data from "len" so "sys.stdin.readline" can actually add new data.

GitHub Repo here with full code

Top answer
1 of 6
27

stdin.read(1) reads one character from stdin. If there was more than one character to be read at that point (e.g. the newline that followed the one character that was read in) then that character or characters will still be in the buffer waiting for the next read() or readline().

As an example, given rd.py:

from sys import stdin

x = stdin.read(1)
userinput = stdin.readline()
betAmount = int(userinput)
print ("x=",x)
print ("userinput=",userinput)
print ("betAmount=",betAmount)

... if I run this script as follows (I've typed in the 234):

C:\>python rd.py
234
x= 2
userinput= 34

betAmount= 34

... so the 2 is being picked up first, leaving the 34 and the trailing newline character to be picked up by the readline().

I'd suggest fixing the problem by using readline() rather than read() under most circumstances.

2 of 6
11

Simon's answer and Volcano's together explain what you're doing wrong, and Simon explains how you can fix it by redesigning your interface.

But if you really need to read 1 character, and then later read 1 line, you can do that. It's not trivial, and it's different on Windows vs. everything else.

There are actually three cases: a Unix tty, a Windows DOS prompt, or a regular file (redirected file/pipe) on either platform. And you have to handle them differently.

First, to check if stdin is a tty (both Windows and Unix varieties), you just call sys.stdin.isatty(). That part is cross-platform.

For the non-tty case, it's easy. It may actually just work. If it doesn't, you can just read from the unbuffered object underneath sys.stdin. In Python 3, this just means sys.stdin.buffer.raw.read(1) and sys.stdin.buffer.raw.readline(). However, this will get you encoded bytes, rather than strings, so you will need to call .decode(sys.stdin.decoding) on the results; you can wrap that all up in a function.

For the tty case on Windows, however, input will still be line buffered even on the raw buffer. The only way around this is to use the Console I/O functions instead of normal file I/O. So, instead of stdin.read(1), you do msvcrt.getwch().

For the tty case on Unix, you have to set the terminal to raw mode instead of the usual line-discipline mode. Once you do that, you can use the same sys.stdin.buffer.read(1), etc., and it will just work. If you're willing to do that permanently (until the end of your script), it's easy, with the tty.setraw function. If you want to return to line-discipline mode later, you'll need to use the termios module. This looks scary, but if you just stash the results of termios.tcgetattr(sys.stdin.fileno()) before calling setraw, then do termios.tcsetattr(sys.stdin.fileno(), TCSAFLUSH, stash), you don't have to learn what all those fiddly bits mean.

On both platforms, mixing console I/O and raw terminal mode is painful. You definitely can't use the sys.stdin buffer if you've ever done any console/raw reading; you can only use sys.stdin.buffer.raw. You could always replace readline by reading character by character until you get a newline… but if the user tries to edit his entry by using backspace, arrows, emacs-style command keys, etc., you're going to get all those as raw keypresses, which you don't want to deal with.

Find elsewhere
🌐
GeeksforGeeks
geeksforgeeks.org › difference-between-input-and-sys-stdin-readline
Difference between input() and sys.stdin.readline() - GeeksforGeeks
October 29, 2021 - Stdin stands for standard input which is a stream from which the program reads its input data. This method is slightly different from the input() method as it also reads the escape character entered by the user. More this method also provides the parameter for the size i.e. how many characters it can read at a time. Example: ... # Python program to demonstrate # sys.stdin.readline() import sys name = sys.stdin.readline() print(name) num = sys.stdin.readline(2) print(num) Output:
🌐
Haxe Community
community.haxe.org › t › solved-sys-stdin-not-reading-stdout › 3378
[SOLVED] Sys.stdin() not reading stdout - haxe-cpp - Haxe Community
December 15, 2021 - I’m trying to pipe data into my app. I’m using Process to run a command which outputs to stdout. If I try to read that output, using the methods available to Sys.stdin(), the app becomes unresponsive, seemingly waiting for keyboard input in the terminal. It does not seem to be receiving ...
🌐
Python
bugs.python.org › issue18597
Issue 18597: On Windows sys.stdin.readline() doesn't handle Ctrl-C properly - Python tracker
This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/62797
🌐
Reddit
reddit.com › r/learnpython › [beginners] intro to reading from standard input
r/learnpython on Reddit: [BEGINNERS] Intro to reading from standard input
January 6, 2018 -

Hey everyone, I just want to talk about reading in data from standard input and the 4 main ways it can be done.

I'm not going to talk about the input() or raw_input() functions today, instead ill be talking about how to read from standard input using the sys module.

To get access to the sys module we first need to import it

import sys

Ok now we have access to this module, there are 3 ways to read from standard input:

  1. sys.stdin.read([size])

  2. sys.stdin.readline()

  3. sys.stdin.readlines()

Lets look at how all of these work first and the ways to use them.

First off we can read lines directly from the console, this will look something like this

lines = sys.stdin.read()
print(lines)

$ python3 stdin.py
Line1
Line 2
**END**
Line 1
Line 2

Our lines variable looks like this: "Line1\nLine2"

Here when we run our program, it waits until it we pass some data through the console window. We specify end of input using ctrl+z on windows and I believe ctrl+d on linux.

The sys.stdin.read() function also has an optional parameter for the size of the data we want to read. For example if we pass 10 then it reads 10 characters including any newline characters.

The read() function will read everything, or the size of data specified, and return it as one string. This is useful for small amounts of data but if we read large files this way, it can use up a lot of memory.

The second way is sys.stdin.readline() which is self explanatory and reads a single line from standard input with a newline character at the end.

line = sys.stdin.readline()
print(line)

$ python3 stdin.py
hello
hello

The next way is sys.stdin.readlines(). I find myself using this way most often. With this way, we read lines from the console and are returned a list containing all the lines we entered.

lines = sys.stdin.readlines()
print(lines)

$ python3 stdin.py
line1
line2
line3
['line1\n', 'line2\n', 'line3\n']

This is very useful if we wish to process a file line by line although, we do have a large list sitting in memory which we may not want with large files. I will show you how to read from files in a moment.

Reading from files:

To read from a file we can do this a couple of ways, we can open and read the file within our program.

with open('FILENAME', [rw]) as our_file:
    for line in our_file:
        print(line)

The optional [rw] specifies whether we wish to open the file for reading, r or writing, w. This will work depending on the access permission on the file. You can check this on linux from the command line by navigating to your directory where the file is and typing:

$ ls -l

This will display the access permissions of the file in that directory.

An error will be thrown if you try to read or write without having permission to do so.

If the file name you entered doesn't exist, an empty file will be created for you.

The use of with open() here is very useful as it closes our file for us when we are finished.

Another way to read a file is passing it at the command line

$ python3 stdin.py < FILENAME.txt

Presuming FILENAME.txt looks like this:

Line 1
Line 2
Line 3

Running the following program, we get the following output:

import sys

lines = sys.stdin.readlines()
print(lines)

$ python3 stdin.py < FILENAME.txt
['Line 1\n', 'Line 2\n', 'Line 3']

I dont want to talk to much about the different ways of reading and writing files as I only wanted to talk about the different methods we have available to use for reading so I wont discuss any further ways of reading.

If we wish to strip the newline characters from our lines we can use the strip() method, I'm going to use a list comprehension here as it is a good example of their usage:

lines = [line.strip() for line in sys.stdin.readlines()]
print(lines)

$ python3 stdin.py < FILENAME.txt
['Line 1', Line 2', 'Line 3']

Whats the list comprehension doing? It uses a for loop to loop through each line in standard input, takes each line and strips it then appends it to our list, lines.

Now our newline characters are gone.

We covered a fair bit of stuff here and got the chance to see some extra things in use such as list comprehensions. If you found anything here confusing, play around with it yourself, after all its one of the best ways to learn.

🌐
Edureka Community
edureka.co › home › community › categories › python › input vs sys stdin read
input vs sys stdin read | Edureka Community
July 23, 2019 - import sys s1 = input() s2 = sys.stdin.read(1) #type "s" for example s1 == "s" #False s2 == ... ? I tried to encode/decode s1, but it doesn't work.
Top answer
1 of 2
2

@Adar70
EOF is not a character you can send, it's a state/condition, which is true when end of file is detected. For a process sending the data (as opposed to reading from a file) that requires either to terminate/exit the sending process (your QProcess) --- which will mean it won't be there to read the response back in your case --- or you must close stdout, QProcess::closeWriteChannel() --- which will mean you won't be able to send any further messages to the subprocess, which may or may not be acceptable in your situation.

However, better, I will bet my bottom dollar that Python has a way of reading from stdin which does not require EOF. That is down to your statements like sys.stdin.read(), which is a Python question. You want some kind of "unbuffered" and "return immediately with what is there". That is for you to look up. I don't think you should read from sys.stdin.buffer, that is likely to be buffered. Why don't you start with os.read(0, 5) --- read 5 bytes from file descriptor 0, which is stdin, and should be unbuffered --- and see if that works?

Failing that you might try sending a \n at the end of your message, if Python's stdin is line-buffered that may work. If you had sent the data from Pythion via print(..., flush=True) that would have added a \n and I believe that would allow reader to use e.g. for line in sys.stdin (or equivalent for one line) and receive the line immediately. However, your data looks like arbitrary binary data, not text, so the whole idea of inserting a \n or reading "lines" may not be appropriate here.

You might also temporarily try writing the sender side in Python too while you get it working.

2 of 2
2

The thing is you call start and right after your write something to the stdin however there's no guarantee that your script has started at this point.
You should use the started signal to then write to the process and you should also connect the errorOccurred signal because you never know what might go wrong.

🌐
Benjdd
benjdd.com › courses › cs250 › spring-2017 › lectures › python-read-stdin.html
CSc 250: Lecture Notes: reading from stdin
Once we have read them all in, they will be used to construct the MadLib story that it printed to stdout. Below is an example run: Notice how each time one of the lines containing sys.stdin.readline().rstrip() is reached, the program “pauses” so that it can read input from a user.
🌐
GitHub
github.com › spyder-ide › spyder › issues › 16990
problems about sys.stdin.read() in ipython console · Issue #16990 · spyder-ide/spyder
December 9, 2021 - sys.stdin.read() is unavaliable in IPython Console. ... because of these questions, I cannot use standard io by os.read or os.write in IPython Console, which is meaningful to my continued work
Author   DuanYuFi
🌐
Python
bugs.python.org › issue17620
Issue 17620: Python interactive console doesn't use sys.stdin for input - Python tracker
April 2, 2013 - This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide · This issue has been migrated to GitHub: https://github.com/python/cpython/issues/61820