[Tutor] execute an OS command, get the output

w chun wescpy at gmail.com
Mon Mar 13 01:09:42 CET 2006


yup, that's right.  turns out that it doesn't really matter whether
the cmd is run in a shell or not -- that's one of the great things
about subprocess -- you get to choose.  with os.system(), *everything*
is run through the shell.

apparently, this problem isn't new... the problem is that the other
program doesn't provide unbuffered output.  i don't know why it works
in pure shell (and not programming pipes) environment, but it does. 
here is someone else that run into it, and they had access to the C
source to the other program to add a flush() call to get the
communication the way they want it (similar to my desired output):

http://www.dalkescientific.com/writings/diary/archive/2005/04/15/wrapping_command_line_programs_II.html

cheers,
-wesley

ps. on Mac OS X, their 'tr' command has a "-u" (unbuffered output)
version, and once i added that option, my code worked exactly the want
i desired.  so i'm only SOL on the Linux one.  :-)


On 3/12/06, Alan Gauld <alan.gauld at freenet.co.uk> wrote:
> 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

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
"Core Python Programming", Prentice Hall, (c)2006,2001
    http://corepython.com

wesley.j.chun :: wescpy-at-gmail.com
cyberweb.consulting : silicon valley, ca
http://cyberwebconsulting.com


More information about the Tutor mailing list