Python piping on Windows: Why does this not work?
Asked Answered
B

3

11

I'm trying something like this

Output.py

print "Hello"

Input.py

greeting = raw_input("Give me the greeting. ")
print "The greeting is:", greeting

At the cmd line

Output.py | Input.py

But it returns an EOFError. Can someone tell me what I am doing wrong?

Thanks for your help.

EDIT
Patrick Harrington solution works but I don't know why...

Bistort answered 21/1, 2009 at 20:20 Comment(3)
That is, I used input(..) instead of raw_input(..)Globigerina
I've updated my answer to explain why the solution Patrick and I proposed works and the original does not.Monticule
updated again with an alternate solution (adding registry key) to avoid needing to specify the python executable in calling input.pyMonticule
M
23

I tested this on my Windows machine and it works if you specify the Python exe:

C:\>C:\Python25\python.exe output.py | C:\Python25\python.exe input.py
Give me the greeting. The greeting is: hello

But I get an EOFError also if running the commands directly as:

output.py | input.py 

I'm not sure exactly why that is, I'm still looking into this one but at least this should provide you with a workaround for now. It may have something to do with the way the file handler is invoked for .py files.

UPDATE: well, what do you know. Looks like this is actually a bug in Windows where stdin/stdout redirection may not work properly when started from a file association. So the workaround is as noted by myself and Patrick, you need to specify "python" will be running input.py, otherwise it will not redirect stdout from output.py to the stdin for input.py correctly.

Reference:

http://mail.python.org/pipermail/python-bugs-list/2004-August/024923.html

http://support.microsoft.com/default.aspx?kbid=321788

UPDATE 2:

To change this behavior and make Windows pipes work as expected for stdin/stdout redirection, you can add this value to the registry (tested on my box and verified this works as desired).

  1. Start Registry Editor.
  2. Locate and then click the following key in the registry:

    HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer

  3. On the Edit menu, click Add Value, and then add the following registry value:

    Value name: InheritConsoleHandles
    Data type: REG_DWORD
    Radix: Decimal
    Value data: 1

  4. Quit Registry Editor.

Monticule answered 21/1, 2009 at 20:30 Comment(1)
It is worth mentioning that now you can add InheritConsoleHandles value to Windows registry to use output.py | input.py as described in the linked microsoft.com page.Ardithardme
S
4

Change it to:

Output.py | python Input.py

The output will be:

Give me the greeting. The greeting is: hello

Sequela answered 21/1, 2009 at 20:30 Comment(0)
H
0

Here's why you get the EOFError (from the documentation on raw_input):

The function then reads a line from input, converts it to a string (stripping a trailing newline), and returns that. When EOF is read, EOFError is raised.

http://docs.python.org/library/functions.html?highlight=raw_input#raw_input

You may want to use sys.stdin, it provides a file object from which you can use the read, readlines methods.

import sys
for greeting_line in sys.stdin.readlines():
    print "The greeting is:", greeting_line.strip()
Homeopathic answered 22/1, 2009 at 1:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.