LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-23-2021, 08:49 AM   #1
mimorek
Member
 
Registered: Feb 2013
Distribution: Debian (jessie)
Posts: 42

Rep: Reputation: Disabled
Python can't read script from stdin when input() appears in the script.


Hello,

When I let python run a short script from stdin it works, but not when the input() function appears in the script.
What is behind the EOFError and is there a way to make this work?

Thanks.

This fails:
Code:
$ python3 <<HERE
> x = input()
> x = int(x)
> print(x**3)
> HERE
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
EOFError: EOF when reading a line

This works:
Code:
$ python3 <<HERE
> x = 3**3
> print(x)
> HERE
27
 
Old 04-23-2021, 08:59 AM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,170
Blog Entries: 1

Rep: Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536
When you redirect the stdin of python executable, it is not a Python-script. Python script is a file like this:
Code:
#!/usr/bin/python3
x = input()
x = int(x)
print(x**3)
Two ways to run it (assuming its name is `test3.py`):
Code:
python3 test3.py
chmod +x test3.py; ./test3.py

Last edited by NevemTeve; 04-23-2021 at 09:02 AM.
 
Old 04-23-2021, 09:04 AM   #3
mimorek
Member
 
Registered: Feb 2013
Distribution: Debian (jessie)
Posts: 42

Original Poster
Rep: Reputation: Disabled
But that still doesn't work.

Code:
$ python3 <<HERE
> #!/usr/bin/python3
> x = input()
> x = int(x)
> print(x**3)
> HERE
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
EOFError: EOF when reading a line
 
Old 04-23-2021, 09:13 AM   #4
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,170
Blog Entries: 1

Rep: Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536
Indeed, it doesn't work, that's why I suggest creating an actual script instead.

Edit: as an experiment, you could try this:
Code:
python3 <<HERE
x = input()
42
x = int(x)
print(x**3)
HERE

Last edited by NevemTeve; 04-23-2021 at 09:18 AM.
 
Old 04-23-2021, 09:27 AM   #5
mimorek
Member
 
Registered: Feb 2013
Distribution: Debian (jessie)
Posts: 42

Original Poster
Rep: Reputation: Disabled
I think I haven't explained my question well.
I am trying to run this from the Bash cli. I am not creating a file.
 
Old 04-23-2021, 09:32 AM   #6
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 1,339

Rep: Reputation: 1132Reputation: 1132Reputation: 1132Reputation: 1132Reputation: 1132Reputation: 1132Reputation: 1132Reputation: 1132Reputation: 1132

There's no need to create a file - as per "python3 --help" you can pass a string using -c option:
Code:
$ python3 -c 'print(int(input())**3)'
5
125

But I think mimorek's question is why the first of these works but the second doesn't:
Code:
$ echo 'print(int('5')**3)' | python3
125

$ echo 'print(int(input())**3)' | python3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
EOFError: EOF when reading a line
I suspect the answer is something to do with because the script is passed via stdin, there is then no stdin for the script to read from.


When the script is not provided over stdin, then input() can be used to read from it:
Code:
$ echo 5 | python3 -c 'print(int(input())**3)'
125

Last edited by boughtonp; 04-23-2021 at 09:36 AM.
 
Old 04-23-2021, 09:54 AM   #7
Ser Olmy
Senior Member
 
Registered: Jan 2012
Distribution: Slackware
Posts: 3,063

Rep: Reputation: Disabled
Quote:
Originally Posted by mimorek View Post
But that still doesn't work.
Code:
$ python3 <<HERE
So you're telling the shell to feed the python3 executable some text via stdin. OK.
Quote:
Originally Posted by mimorek View Post
Code:
> x = input()
And then you wonder why stdin isn't available for reading input?
 
Old 04-23-2021, 09:56 AM   #8
michaelk
Moderator
 
Registered: Aug 2002
Posts: 21,491

Rep: Reputation: 4106Reputation: 4106Reputation: 4106Reputation: 4106Reputation: 4106Reputation: 4106Reputation: 4106Reputation: 4106Reputation: 4106Reputation: 4106Reputation: 4106
boughtonp is correct python no longer has access to stdin and there are a few ways to work around the problem. Here is your code as posted.
Code:
#!/bin/bash
python3 <(cat <<HERE
x = input()
x = int(x)
print(x**3)
HERE
)

#!/bin/bash
python3 -c '
x = input()
x = int(x)
print(x**3)
'
 
Old 04-23-2021, 10:07 AM   #9
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 16,490

Rep: Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532Reputation: 5532
Code:
$ python3 <<HERE
> x = 3**3
> print(x)
> HERE
27
here python3 will read stdin and take it as a script (and execute it).
Code:
$ python3 <<HERE
> #!/usr/bin/python3
> x = input()
> x = int(x)
> print(x**3)
> HERE
here python3 will read stdin and x=input will also read the same stdin. The result is that python3 will not find the end of the file (because slurped by that input call).
 
Old 04-23-2021, 11:36 PM   #10
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,170
Blog Entries: 1

Rep: Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536Reputation: 1536
I tried the suggested experiment, it doesn't work either. The reason is simple: python3 executable reads the input in blocks (4096 byte in my example).
Part of `strace` output:
Code:
read(0, "x = input()\n42\nx = int(x)\nprint("..., 4096) = 38
read(0, "", 4096)                       = 0
...
read(0, "", 8192)                       = 0
The first `read` gets everything (38 bytes); the second `read` returns 0 to indicate end-of-file (EOF), the third `read` is the `input` in the program which also returns 0 (end-of-file).
 
Old 04-24-2021, 08:14 AM   #11
mimorek
Member
 
Registered: Feb 2013
Distribution: Debian (jessie)
Posts: 42

Original Poster
Rep: Reputation: Disabled
Thanks for responding everybody.
It makes more sense to me now.

The answer michaelk provided kept me puzzled and searching for quite a while:
Code:
python3 <(cat <<HERE
x = input()
x = int(x)
print(x**3)
HERE
)
But now I've learned that process substitution treats its output as a file and it is no longer stdin:
Code:
python3 <( cat <<HERE
import sys
print(sys.argv)
HERE
)
['/dev/fd/63']      <-- output
from the bash manpage:

"Process Substitution
Process substitution allows a process's input or output to be referred to using a filename."
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Can ls take input from stdin? stf92 Linux - Newbie 9 07-05-2011 08:37 AM
LXer: Python Python Python (aka Python 3) LXer Syndicated Linux News 0 08-05-2009 08:30 PM
how can a program tell if it has stdin "waiting" to be read? aryek Linux - Software 1 07-09-2009 02:14 PM
read from stdin in a shell script bujecas Linux - General 3 07-03-2009 04:46 PM
Python: Stdin and python apps fighting? enigma_0Z Programming 2 07-15-2008 08:45 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 11:53 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration