1

I want to run a python 3 script giving it a file via stdin or manually typing data.

E.g. let's suppose I want to print the contents of an input with one line. The script, called app.py would look something like this:

from sys import stdin

print("Input says:"+stdin.readline())

Then, I could run it in both of the following ways:

1. Passing a file as stdin

python app.py < input.txt

2. Prompt the user for the input

python app.py

My problem is that in both cases, after reading stdin I would like to prompt the user for some extra data. Following the before mentioned example it would be:

from sys import stdin

print("Input says:"+stdin.readline())

print("Did you like that? (Yes/No)")
ans = input() # This line is the issue!
if( ans == "Yes"):
    print("You liked it!")    

The commented line above works perfectly for case 2, but for case 1 it throws an EOFError: EOF when reading a line error because it tries to read from the file.

I would like to know if before that line I could do something like

sys.stdin = SOMETHING

Where SOMETHING represents the Windows Console input. I think that if I could do that, then both cases would work properly.

3
  • You may be able to reach around to the console via the win32console api. Commented Dec 4, 2014 at 19:18
  • Try CON or CONIN$. Might work, depending on what exactly Python does with it. Commented Dec 4, 2014 at 21:13
  • Your question is not clear; you want to prompt from the console for some input, even though you have supplied a file as sys.stdin. Commented Jul 30, 2016 at 17:37

1 Answer 1

1

You could consider both cases to be the same (ignore the difference). Your script just reads two lines from stdin. stdin may be redirected from a file or it can be attached to the console, your script can work the same in many cases:

print("Read the first line from stdin", input())
answer = input("Did you like that? (Yes/No): ") # read 2nd line
if answer == "Yes":
    print("You liked it!")

See executable code example.

Q: What I wanted was to read some inputs from a file OR from the console (depending on the parameters used when the app was ran). Some other lines I wanted them to be always read from the console.

To read from the console directly regardless whether stdin is redirected from a file or not, you could use msvcrt.getwch(). See example usage in getpass.win_getpass().

If you have issues with accepting Unicode input; install win_unicode_console package. You can enable it globally for your python installation or for a specific user or for a script as a whole or temporarily using win_unicode_console.enable()/.disable(). To force it to use console, you could set sys.stdin=None temporarily if stdin is redirected or call ReadConsoleW() yourself (cumbersome).

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

8 Comments

The line answer = input("Did you like that? (Yes/No): ") throws an EOFError if I use a file as input. Anyway, that is supposed to happen since it will try to read an input from the file!
@Sam: have you tried to click on "executable code example" link? There is no EOFError. How do you think ideone provides input to the script? (there are no people that type the input). EOFError may be raised at the end of file (portable code should handle EOFError exception) -- I don't know the exact conditions: it is a good question on its own. The point of my answer that you should ignore the difference between: cat input | python your_script.py, <input python your_script.py and manually providing input from terminal/console (unless you have a specific reason not to ignore it).
Yes, that works because stdin has both the first line (data that is there before the execution) and the "Yes" line which is supposed to be typed by the user at runtime. Basically, I what I want is to change the reference sys.stdin from the stream related to the file I give as input (not as argument!) to the stream related to the console's input.
@Sam: Do you want to read the first line from a file and the second line from the console? It is possible to redirect sys.stdin in the middle of a program to read from console (just assign sys.stdin a file-like object that reads from console directly e.g., using Win32 API (it might not have any effect on input(); use sys.stdin.readline() in that case) or a special filename such as con as suggested in the comments. But a better alternative is to avoid redirecting stdin in the middle of a program; read from a file using a filename instead.
@Sam: I've updated the answer to mention explicitly how to read from the console directly regardless whether stdin is redirected or not.
|

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.