How do you read from stdin in Python?

I'm trying to do some of the code golf challenges, but they all require the input to be taken from stdin. How do I get that in Python?

You just need to read from sys.stdin.

TLDR: compatible with Python 2 and 3, Windows, Unix

Say you have a file, inputs.txt, we can accept that file and write it back out:

python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt

Longer answer

Here's a complete, easily replicable demo, using two methods, the builtin function, input (use raw_input in Python 2), and sys.stdin. The data is unmodified, so the processing is a non-operation.

To begin with, let's create a file for inputs:

$ python -c "print('foo\nbar\nbaz')" > inputs.txt

And using the code we've already seen, we can check that we've created the file:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt 
foo
bar
baz

Here's the help on sys.stdin.read from Python 3:

read(size=-1, /) method of _io.TextIOWrapper instance
    Read at most n characters from stream.

    Read from underlying buffer until we have n characters or we hit EOF.
    If n is negative or omitted, read until EOF.

Builtin function, input (raw_input in Python 2)

The builtin function input reads from standard input up to a newline, which is stripped (complementing print, which adds a newline by default.) This occurs until it gets EOF (End Of File), at which point it raises EOFError.

Thus, here's how you can use input in Python 3 (or raw_input in Python 2) to read from stdin - so we create a Python module we call stdindemo.py:

$ python -c "print('try:\n    while True:\n        print(input())\nexcept EOFError:\n    pass')" > stdindemo.py 

And let's print it back out to ensure it's as we expect:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo.py 
try:
    while True:
        print(input())
except EOFError:
    pass

Again, input reads up until the newline and essentially strips it from the line. print adds a newline. So while they both modify the input, their modifications cancel. (So they are essentially each other's complement.)

And when input gets the end-of-file character, it raises EOFError, which we ignore and then exit from the program.

And on Linux/Unix, we can pipe from cat:

$ cat inputs.txt | python -m stdindemo
foo
bar
baz

Or we can just redirect the file from stdin:

$ python -m stdindemo < inputs.txt 
foo
bar
baz

We can also execute the module as a script:

$ python stdindemo.py < inputs.txt 
foo
bar
baz

Here's the help on the builtin input from Python 3:

input(prompt=None, /)
    Read a string from standard input.  The trailing newline is stripped.

    The prompt string, if given, is printed to standard output without a
    trailing newline before reading input.

    If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.
    On *nix systems, readline is used if available.

sys.stdin

Here we make a demo script using sys.stdin. The efficient way to iterate over a file-like object is to use the file-like object as an iterator. The complementary method to write to stdout from this input is to simply use sys.stdout.write:

$ python -c "print('import sys\nfor line in sys.stdin:\n    sys.stdout.write(line)')" > stdindemo2.py

Print it back out to make sure it looks right:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo2.py 
import sys
for line in sys.stdin:
    sys.stdout.write(line)

And redirecting the inputs into the file:

$ python -m stdindemo2 < inputs.txt
foo
bar
baz

Golfed into a command:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
foo
bar
baz

File Descriptors for Golfing

Since the file descriptors for stdin and stdout are 0 and 1 respectively, we can also pass those to open in Python 3 (not 2, and note that we still need the 'w' for writing to stdout).

If this works on your system, it will shave off more characters.

$ python -c "open(1,'w').write(open(0).read())" < inputs.txt
baz
bar
foo

Python 2's io.open does this as well, but the import takes a lot more space:

$ python -c "from io import open; open(1,'w').write(open(0).read())" < inputs.txt 
foo
bar
baz

PS I spent a lot of effort trying to make these demos work cross-platform. The Python is consistent, but the shell entries are not very flexible. However, making this accessible to people on Windows as well as Linux was important to me. Let me know if you have issues with Windows.

share|improve this answer

One option is to use input function as shown below. There is also raw_input method if you are not sure about the data type.

#!/usr/bin/env python

number = input("Please enter a number : ")
print("Entered number is %d" % number)

Running the program:

python test1.py

Please enter a number : 55
Entered number is 55

Reference: http://www.python-course.eu/input.php

share|improve this answer

I am pretty amazed no one had mentioned this hack so far:

python -c "import sys;print (''.join([l for l in sys.stdin.readlines()]))"

compatible with both python2 and python3

share|improve this answer

Regarding this:

for line in sys.stdin:

I just tried it on python 2.7 (following someone else's suggestion) for a very large file, and I don't recommend it, precisely for the reasons mentioned above (nothing happens for a long time).

I ended up with a slightly more pythonic solution (and it works on bigger files):

with open(sys.argv[1], 'r') as f:
    for line in f:

Then I can run the script locally as:

python myscript.py "0 1 2 3 4..." # can be a multi-line string or filename - any std.in input will work
share|improve this answer
    
Opening a file is not reading from stdin, like the question asks. -1 – Aaron Hall Aug 1 '16 at 13:27
    
sys.stdin is a file-like object – szeitlin Aug 1 '16 at 19:19
    
sys.stdin being a file-like object does not mean that all file-like objects are sys.stdin. – Aaron Hall Aug 1 '16 at 21:45
    
In this case I am passing in sys.stdin as a command-line argument to the script. – szeitlin Aug 1 '16 at 22:56
1  
How could you pass sys.stdin as a command-line argument to the script? Arguments are strings and streams are file-like objects, they are not the same. – DeFazer Sep 17 '16 at 2:12

Read from sys.stdin, but to read binary data on Windows, you need to be extra careful, because sys.stdin there is opened in text mode and it will corrupt \r\n replacing them with \n.

The solution is to set mode to binary if Windows + Python 2 is detected, and on Python 3 use sys.stdin.buffer.

import sys

PY3K = sys.version_info >= (3, 0)

if PY3K:
    source = sys.stdin.buffer
else:
    # Python 2 on Windows opens sys.stdin in text mode, and
    # binary data that read from it becomes corrupted on \r\n
    if sys.platform == "win32":
        # set sys.stdin to binary mode
        import os, msvcrt
        msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
    source = sys.stdin

b = source.read()
share|improve this answer

Python also has built-in functions input() and raw_input(). See the Python documentation under Built-in Functions or the Stack-Overflow documentation under User Input.

For example,

name = raw_input("Enter your name: ")   # Python 2.x

or

name = input("Enter your name: ")   # Python 3
share|improve this answer
    
This reads a single line, which isn't really what the OP asked about. I interpret the question as "how do I read a bunch of lines from an open file handle until EOF?" – tripleee Dec 22 '15 at 8:51
    
On another answer here, I demonstrate how to use input to read an entire file in, and input does exactly what the question asks. – Aaron Hall Aug 1 '16 at 14:58

There's a few ways to do it.

  • sys.stdin is a file-like object on which you can call functions read or readlines if you want to read everything or you want to read everything and split it by newline automatically. (You need to import sys for this to work.)

  • If you want to prompt the user for input, you can use raw_input in Python 2.X, and just input in Python 3.

  • If you actually just want to read command-line options, you can access them via the sys.argv list.

You will probably find this Wikibook article on I/O in Python to be a useful reference as well.

share|improve this answer
2  
the prompting is optional – newacct Sep 20 '09 at 7:51
15  
The prompt (waiting for user input) isn't optional, but displaying prompt text is. – 2rs2ts Dec 7 '11 at 9:03
1  
I like this solution. I transferred from python 2.7.5 to python 3.4 and was wondering why raw_input wasn't working – corvid Mar 29 '14 at 20:22
    
I explain 2rs2ts's cryptic comment in this answer – Aaron Hall Aug 1 '16 at 15:00

The following chip of code will help you :

input_str = sys.stdin.read()
print input_str.split()
share|improve this answer

You could use the fileinput module:

import fileinput

for line in fileinput.input():
    pass

fileinput will loop through all the lines in the input specified as file names given in command-line arguments, or the standard input if no arguments are provided.

share|improve this answer
37  
This is what you want (albeit not what you asked for). Users can pass data to your application by either argument format.py addresses.txt or standard input cat addresses.txt | format.py. This makes your app more usable (note that grep and the rest of Unix can be used either way) – Colonel Panic Aug 14 '12 at 10:18
12  
So this is the Python equivalent of Perl's while(<>) ? – Kyle Strand May 8 '13 at 23:05
13  
@Val You are using the wrong tool, this allows you to read a bunch of lines which can then be terminated with EOF (Ctrl + D). To read a single line ("prompt"), see the other answer. – Lekensteyn Oct 2 '13 at 21:13
16  
How does this coexist with argparse? – Nick T Aug 28 '14 at 0:14
15  
@NickT to make it work with argparse, I used args, unk = parse_known_args() instead of args = parse_args(), and used unk as the list of files: fileinput.input(unk). – gwenzek Sep 1 '14 at 16:20

Building on all the anwers using sys.stdin, you can also do something like the following to read from an argument file if at least one argument exists, and fall back to stdin otherwise:

import sys
f = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin    
for line in f:
#     Do your stuff

and use it as either

$ python do-my-stuff.py infile.txt

or

$ cat infile.txt | python do-my-stuff.py

or even

$ python do-my-stuff.py < infile.txt

That would make your Python script behave like many GNU/Unix programs such as cat, grep and sed.

share|improve this answer

I had some issues when getting this to work for reading over sockets piped to it. When the socket got closed it started returning empty string in an active loop. So this is my solution to it (which I only tested in linux, but hope it works in all other systems)

import sys, os
sep=os.linesep

while sep == os.linesep:
    data = sys.stdin.readline()               
    sep = data[-len(os.linesep):]
    print '> "%s"' % data.strip()

So if you start listening on a socket it will work properly (e.g. in bash):

while :; do nc -l 12345 | python test.py ; done

And you can call it with telnet or just point a browser to localhost:12345

share|improve this answer

The answer proposed by others:

for line in sys.stdin:
  print line

is very simple and pythonic, but it must be noted that the script will wait until EOF before starting to iterate on the lines of input.

This means that tail -f error_log | myscript.py will not process lines as expected.

The correct script for such a use case would be:

while 1:
    try:
        line = sys.stdin.readline()
    except KeyboardInterrupt:
        break

    if not line:
        break

    print line

UPDATE
From the comments it has been cleared that on python 2 only there might be buffering involved, so that you end up waiting for the buffer to fill or EOF before the print call is issued.

share|improve this answer
6  
Are you sure? I'm running this with 3.2.2 and each line is echoed as I type. – Graham Lea Oct 27 '11 at 9:49
1  
I just tried it again and it indeed seems to work correctly. Not sure if it was a bug in my python interpreter or what but I'm fairly sure that it did not work before. Thanks for bringing this up! – Massimiliano Torromeo Oct 27 '11 at 10:22
6  
The for line in sys.stdin: pattern does not wait for EOF. But if you test on very small files, responses may get buffered. Test with more data to see that it reads intermediate results. – mb. Jul 11 '12 at 2:06
2  
I suspect this is related to detection of tty in libc, so when you pipe it detects on a interactive shell it detects none tty, unbuffer from expect-dev is a handy util that I believe injects a shim via ld_preload so is_atty returns true (I suspect that's how it is handing it) – Mâtt Frëëman Mar 12 '15 at 8:16
3  
@Sean: wrong. for line in sys.stdin: does not "block till EOF". There is a read-ahead bug in Python 2 that delays the lines until the corresponding buffer is full. It is a buffering issue that is unrelated to EOF. To workaround, use for line in iter(sys.stdin.readline, ''): (use io.open() for ordinary files). You don't need it in Python 3. – J.F. Sebastian Jan 23 '16 at 7:38

Try this:

import sys

print sys.stdin.read().upper()

and check it with:

$ echo "Hello World" | python myFile.py
share|improve this answer

Here's from Learning Python:

import sys
data = sys.stdin.readlines()
print "Counted", len(data), "lines."

On Unix, you could test it by doing something like:

% cat countlines.py | python countlines.py 
Counted 3 lines.

On Windows or DOS, you'd do:

C:\> type countlines.py | python countlines.py 
Counted 3 lines.
share|improve this answer
2  
I'm having this problem with the first two lines in Python 3.2 ` data = sys.stdin.readlines() AttributeError: 'NoneType' object has no attribute 'readlines'` – Jader Dias Jun 14 '11 at 13:00
3  
Here's a more memory efficient (and maybe faster) way to count lines in Python: print(sum(chunk.count('\n') for chunk in iter(partial(sys.stdin.read, 1 << 15), ''))). see wc-l.py – J.F. Sebastian Nov 16 '12 at 4:32
4  
The use of cat here is redundant. The correct invocation for Unix systems is python countlines.py < countlines.py. – istepaniuk Nov 17 '15 at 11:14
3  
"Learning Python" is wrong in directing users to use readlines(). File objects are intended to be iterated over without materializing all of the data in memory. – Aaron Hall Aug 1 '16 at 14:56

This will echo standard input to standard output:

import sys
line = sys.stdin.readline()
while line:
    print line,
    line = sys.stdin.readline()
share|improve this answer
import sys

for line in sys.stdin:
    print line