[Tutor] execute an OS command, get the output
Alan Gauld
alan.gauld at freenet.co.uk
Sun Mar 12 12:38:09 CET 2006
Wes,
I haven't tried this but I notice you don't specify shell=True in your Popen
calls,
that might be the cause - ypou aren't acting like the shell does.
But aws I say thats just a guess based on a quick scim of your port.
Alan G.
----- Original Message -----
From: "w chun" <wescpy at gmail.com>
To: <tutor at python.org>
Sent: Sunday, March 12, 2006 3:37 AM
Subject: Re: [Tutor] execute an OS command, get the output
ok, while we're on the subject, i thought i should ask a question for
once(!). it's been awhile since i played with pipes, and i ran into
this problem on the same day as this post!
if i'm in the shell and playing with a 2-way game with the 'tr' command like
so:
$ tr '[a-z]' '[A-Z]'
us
US
ca
CA
de
DE
$
i can interactively give the cmd some input via stdin and get
something out of stdout... giving and taking until i press ^D to
terminate the program.
however, when i try this using subprocess/popen2, i find that i can't
do the same interaction, i.e. writing to tr's stdin, reading from tr's
stdout, ad nauseum. it seems that i have to give tr all of my input,
then close tr's stdin pipe in order to read anything. (any attempts
at reading before closing results in a blocked OS call, whether it's
using the FD itself or os.read() on its fileno(). the only way for it
to work as i described above is like this:
>>> p = subprocess.Popen(('tr', '"[a-z]"', '"[A-Z]"'),
stdin=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True)
>>> po, pi = p.stdin, p.stdout
>>> po.write('us\n')
>>> po.write('ca\n')
>>> po.write('de\n')
>>> po.close()
>>> pi.readlines()
['US\n', 'CA\n', 'DE\n']
>>> pi.close()
i was hoping to do somethign more on the lines of:
>>> po.write('us\n')
>>> pi.read() # or pi.readline()
'US\n'
>>> po.write('ca\n')
>>> pi.read()
'CA\n'
but to no avail. neither sending po.write(chr(4)) nor po.flush() seem
to work. i basically can tell whether a read() will block (or not)
using select, as in:
>>> from select import select
>>> sel = select([pi], [], [pi], 0)
>>> sel
([], [], []) <--- MEANS IT WILL BLOCK
or
([<open file '<fdopen>', mode 'r' at 0x39ac80>], [], []) -<- WON'T BLOCK
is there anyway to do more "asynchronous" I/O where i can more or less
interact with the other procses rather than what it's doing now?
thanks you guys... i love the tutors!
-wesley
More information about the Tutor
mailing list