reading piped input in Windows

P

Patrick Useldinger

Hi,
I am writing a filter, i.e. a program that reads from stdin and writes
to stdout. It works ok when run on its own, but does not work when I try
to use another program's output.

- The producer program (t1):
print "a b c"
print "d e f"

- The filter program (t2):
import sys
r = sys.stdin.readlines()
for i in r:
print '<',i,'>'

When i connect them using 't1 ¦ t2', I get the following error message:
Traceback (most recent call last):
File "[...]", line 2, in ?
r = sys.stdin.readlines()
IOError: [Errno 9] Bad file descriptor

The same programs work correctly under Linux, so I suppose that Windows
handles redirectionned input differently from 'normal' console input.
Can anyone point me to a portable solution that works both under Windows
and Linux?

-PU
 
M

Michael Geary

Patrick Useldinger:
I am writing a filter, i.e. a program that reads from stdin and writes
to stdout. It works ok when run on its own, but does not work when I try
to use another program's output.

- The producer program (t1):
print "a b c"
print "d e f"

- The filter program (t2):
import sys
r = sys.stdin.readlines()
for i in r:
print '<',i,'>'

When i connect them using 't1 ¦ t2', I get the following error message:
Traceback (most recent call last):
File "[...]", line 2, in ?
r = sys.stdin.readlines()
IOError: [Errno 9] Bad file descriptor

The same programs work correctly under Linux, so I suppose that Windows
handles redirectionned input differently from 'normal' console input.
Can anyone point me to a portable solution that works both under Windows
and Linux?

It works OK for me on Windows XP SP1 with Python 2.3.2:

C:\Test\PythonTest >>t1.py | t2.py
< a b c

What versions of Windows and Python are you running?

BTW, here's a simpler way to write the loop in t2.py:

import sys
for line in sys.stdin:
print '<', line, '>'

Or this, to get rid of the extra newlines (not clear if those are intended
or not):

import sys
for line in sys.stdin:
print '<', line[:-1], '>'

-Mike
 
B

Bengt Richter

Hi,
I am writing a filter, i.e. a program that reads from stdin and writes
to stdout. It works ok when run on its own, but does not work when I try
to use another program's output.

- The producer program (t1):
print "a b c"
print "d e f"

- The filter program (t2):
import sys
r = sys.stdin.readlines()
for i in r:
print '<',i,'>'

When i connect them using 't1 ¦ t2', I get the following error message:
Traceback (most recent call last):
File "[...]", line 2, in ?
r = sys.stdin.readlines()
IOError: [Errno 9] Bad file descriptor

The same programs work correctly under Linux, so I suppose that Windows
handles redirectionned input differently from 'normal' console input.
Can anyone point me to a portable solution that works both under Windows
and Linux?
Some versions of windows have a bug in i/o redirection for programs started
via data/script file extension association (if you have perl on your machine
you will have the same problem piping to/from perl scripts started by extension association).
It is probable that running the interpreter directly would make it work, e.g.,

python t1.py | python t2.py

But you probably want to spell it t1|t2. On windows, t1 and t2 will have to be
executables to do that reliably across windows versions. Executables are generally
associated with the usual extensions .exe, .com, .bat, and .cmd, so one way to
solve the spelling problem is to provide a t1.bat or t1.cmd that runs python
explicitly with t1.py as arg, as you would do it from the command line, e.g.,
a t1.cmd whose single line content is

@python <absolute directory path to your script>t1.py

This will be slower than also supplying the absolute path to python, but you won't
have to change it when you upgrade and python winds up in c:\python24 instead of c:\python23.
OTOH, if you need a specific version of python to interpret your script, supplying the full
path will lock it in.

Note that a .bat or .cmd invocation of python also gives you the opportunity to pass a
command line option, e.g., python -u drive:\your\path\t1.py to run with unbuffered binary
stdout and stderr.

Regards,
Bengt Richter
 
P

Patrick Useldinger

OK, I should have googled in the first place :-(

For those who wondered, it doesn't work if you have .py extentions
associated with python.exe and just type t1 ¦ p2.

What works is

1- to have a py.cmd which calls python.exe, and then type "py t1.py ¦ py
t2.py",

2- or probably also "python t1.py ¦ python t2.py" if python.exe is in
your path (I didn't check this).

-PU
 
G

Georgy Pruss

Hmmm.

t1.py | t2.py -- doesn't work, because:
t1.py >tt -- DOES work
t2.py <tt -- does NOT work. sys.stdin.fileno() shows -1 instead of 0
python t2.py <tt -- works

What's your Registry key [HKEY_CLASSES_ROOT\Python.File\shell\open\command]?
Mine shows "(default)" = """C:\Apps\Python\python.exe "%1" %*"""
sys.version '2.3 (#46, Jul 29 2003, 18:54:32) [MSC v.1200 32 bit (Intel)]'
sys.getwindowsversion() # XP
(5, 1, 2600, 2, 'Service Pack 1')

G-:
--
Georgy Pruss
E^mail: 'ZDAwMTEyMHQwMzMwQGhvdG1haWwuY29t\n'.decode('base64')


| Patrick Useldinger:
| > I am writing a filter, i.e. a program that reads from stdin and writes
| > to stdout. It works ok when run on its own, but does not work when I try
| > to use another program's output.
| >
| > - The producer program (t1):
| > print "a b c"
| > print "d e f"
| >
| > - The filter program (t2):
| > import sys
| > r = sys.stdin.readlines()
| > for i in r:
| > print '<',i,'>'
| >
| > When i connect them using 't1 ¦ t2', I get the following error message:
| > Traceback (most recent call last):
| > File "[...]", line 2, in ?
| > r = sys.stdin.readlines()
| > IOError: [Errno 9] Bad file descriptor
| >
| > The same programs work correctly under Linux, so I suppose that Windows
| > handles redirectionned input differently from 'normal' console input.
| > Can anyone point me to a portable solution that works both under Windows
| > and Linux?
|
| It works OK for me on Windows XP SP1 with Python 2.3.2:
|
| C:\Test\PythonTest >>t1.py | t2.py
| < a b c
| >
| < d e f
| >
|
| What versions of Windows and Python are you running?
|
| BTW, here's a simpler way to write the loop in t2.py:
|
| import sys
| for line in sys.stdin:
| print '<', line, '>'
|
| Or this, to get rid of the extra newlines (not clear if those are intended
| or not):
|
| import sys
| for line in sys.stdin:
| print '<', line[:-1], '>'
|
| -Mike
|
|
 

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

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,816
Latest member
nipsseyhussle

Latest Threads

Top