Reading twice from STDIN

J

janedenone

Hi,

I would like to read from a pipe, parse the input and ask the user
what to do next:

message = sys.stdin.read()
# message is parsed and URLs are printed as a list to choose from...
selected_index = raw_input('Which URL to open?')

Calling raw_input() always raises in an EOFError. I tried reopening
and resetting sys.stdin, but nothing worked (at least on OX X 10.7,
see http://stackoverflow.com/questions/8034595/python-raw-input-following-sys-stdin-read-throws-eoferror).

I am surprised to find that a seemingly trivial task cannot be
accomplished with Python 2.7 on a current Mac. Or am I missing
something simple?

- Jan
 
G

Gelonida N

On 12/01/2011 11:01 AM, janedenone wrote:
Hi,

I would like to read from a pipe, parse the input and ask the user
what to do next:

message = sys.stdin.read()

With above line you said, that you want to read ALL data from stdin, so
it's obvious that any following command will be unable to reda anything
from standartd in Thus the EOF error.


If you want to get input you had to read directly from the console (tty)
and NOT from stdin. Stdin has already been consumed.

It is possible in python to get the tty related to your console window
and read from it.
Unfortunately I don't kno whte commands by heart and I don't have time
now to look it up.

Perhaps somebody else can point you in the right direction.
If not I'll it up till tomorrow.
 
D

Dan Stromberg

Hi,

I would like to read from a pipe, parse the input and ask the user
what to do next:

message = sys.stdin.read()
# message is parsed and URLs are printed as a list to choose from...
selected_index = raw_input('Which URL to open?')

Calling raw_input() always raises in an EOFError. I tried reopening
and resetting sys.stdin, but nothing worked (at least on OX X 10.7,
see

You can read piped data from sys.stdin normally. Then if you want
something from the user, at least on most *ix's, you would open
/dev/tty and get user input from there. 'Not sure about OS/X.

http://stackoverflow.com/questions/8034595/python-raw-input-following-sys-stdin-read-throws-eoferror).
 
H

Hans Mulder

You can read piped data from sys.stdin normally. Then if you want
something from the user, at least on most *ix's, you would open
/dev/tty and get user input from there. 'Not sure about OS/X.

Reading from /dev/tty works fine on OS/X.

-- HansM
 
J

janedenone

Reading from /dev/tty works fine on OS/X.

-- HansM

Many thanks for the pointers – I had tried

sys.stdin = open('/dev/tty', 'r')

but the actual solution is slightly more complicated. With your help
(and another round of Google searches), I found exactly what I was
looking for:

http://turambar.org/jarkko/stdin_input.php

Because raw_input() (input() in Python 3) reads from file descriptor
0, the solution is to copy this file descriptor elsewhere, and use a
file descriptor pointing to /dev/tty for the user input.

Thanks again - Jan
 
H

Hans Mulder

I had tried

sys.stdin = open('/dev/tty', 'r')

That seems to work for me. This code:

import sys

if sys.version_info.major == 2:
input = raw_input

for tp in enumerate(sys.stdin):
print("%d: %s" % tp)

sys.stdin = open('/dev/tty', 'r')
answer = input('What is the carrying capacity of a swallow? ')
print("You answered: %s" % answer)
print("File descriptor is %d" % sys.stdin.fileno())

.... does what I expect it to do in both Python 2.7 and Python 3.2.
but the actual solution is slightly more complicated. With your help
(and another round of Google searches), I found exactly what I was
looking for:

http://turambar.org/jarkko/stdin_input.php

Because raw_input() (input() in Python 3) reads from file descriptor
0, the solution is to copy this file descriptor elsewhere, and use a
file descriptor pointing to /dev/tty for the user input.

That's odd. For some reason, I can get away with a simple

sys.stdin = open('/dev/tty')

and raw_input will merrily read from file descriptor 3.

I'm using Pyhton 2.7.1 and 3.2 on MacOS/X 10.5.0.

What version are you using?

-- HansM
 
J

janedenone

That's odd.  For some reason, I can get away with a simple

     sys.stdin = open('/dev/tty')

and raw_input will merrily read from file descriptor 3.

I'm using Pyhton 2.7.1 and 3.2 on MacOS/X 10.5.0.

What version are you using?

-- HansM

Python 2.7.1 and 3.2.2 on Mac OS X 10.7.2.

But what's really strange – you're right. It works now. I have no idea
what I did before, but I can confirm that the following code executes
flawlessly:

message = sys.stdin.read()
urls = re.findall(r'(?:http|www)\S+', message)

sys.stdin = open('/dev/tty')
# Asks user to select a URL only if more than one URL is present
if len(urls) > 1:
for index, url in enumerate(urls):
print '{0}: {1}\n'.format(index, url)

selected_index = raw_input('Which URL to open? ')
selected_index = int(selected_index)
else:
selected_index = 0
selected_url = urls[selected_index]

Quite embarrassing. In any case, I am happy to have found the simplest
solution.

Thanks again,
Jan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,037
Latest member
MozzGuardBugs

Latest Threads

Top