I have a script that is designed to accept input piped in from stdin and then prompt the user for more input. Here is a contrived example illustrating what I mean:
import sys
# Get input from stdin
input_nums = [int(n.strip()) for n in sys.stdin]
# Prompt user
mult = int(raw_input("Enter a number by which to multiply your input: "))
for num in input_nums:
print num*mult
When I pipe data in from stdin, python interprets stdin as closed before it gets to raw_input
and it gives an EOFError: EOF when reading a line
:
[user]$ cat nums.txt
2
3
4
5
[user]$ cat nums.txt | python sample.py
Enter a number by which to multiply your input: Traceback (most recent call last):
File "sample.py", line 6, in <module>
mult = int(raw_input("Enter a number by which to multiply your input: "))
EOFError: EOF when reading a line
(Please don't worry about the useless use of cat
... its just a minimal example)
What I want to know is if there is a way to somehow separate reading sys.stdin and calling raw_input
so that I can both pipe in data and then prompt a user for input.
Updated to make it more clear what I really want by eliminating red herrings, and added traceback of EOFError
Result @TimPeter's solution worked for me, but I had to change "CON:" to "/dev/tty" since I'm on UNIX, not Windows.
I suspect you're out of luck, at least for any kind of cross-platform solution. Python uses sys.stdin
for raw_input()
, and if you invoke Python so that sys.stdin
is on the receiving end of a pipe, Python can't do anything to magically change sys.stdin
to the terminal when the piped input ends.
Here's a variant of the question with a Unix-specific workaround as the accepted answer. That cleverly worms around some (not all) of the problem by changing the way the program is invoked.
Sorry.
This seems to work fine for Windows:
import sys
print len(sys.stdin.read()) # anything to consume piped input
sys.stdin = open("CON:", "r")
x = raw_input("sdfklj ")
That is, after reading the piped-in input, sys.stdin
is rebound to the special file CON:
(which is what Windows calls a DOS box) opened in read mode.
See your Unix docs for what to try there - perhaps /dev/tty1
? There are mounds of terminal control options you may need to fiddle with too, depending on platform specifics. That's why I said (at the start) that I think you're out of luck for any cross-platform solution. Python has no special support for terminal devices; i.e., you're on your own for that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With