Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Writing to open subprocess pipes.

361 views
Skip to first unread message

Brandon McGinty

unread,
Jun 16, 2010, 4:29:42 PM6/16/10
to pytho...@python.org
All,
I have researched this both in the python documentation, and via google.
Neither subprocess nor os.popen* will do what I need.
First, I would instanshiate an ongoing shell, that would remain active
throughout the life of the socket connection.
I am trying to take commands, coming in from a standard python socket,
modify them, and then send them onto this shell, /bin/bash, for example.
The output of these modified commands will be received from the shell,
and sent back through the socket, possibly being modified further.
The connection on the other end of the socket will send multiple
commands, and will need output for each.
Both subprocess and os.popen* only allow inputput and output one time,
and the output to be read only when the process terminates.
I need input and output to be read and written continuously, during the
lifetime of the shell.
I hope this makes sense, and if not, I shall do my best to elaborate
further.
I appreciate all the help this group has given me in the past, and I
certainly appreciate any help you all can offer now.

Sincerely,
Brandon McGinty

Ian Kelly

unread,
Jun 16, 2010, 5:27:55 PM6/16/10
to Python
On Wed, Jun 16, 2010 at 2:29 PM, Brandon McGinty
<brandon...@gmail.com> wrote:
> Both subprocess and os.popen* only allow inputput and output one time, and
> the output to be read only when the process terminates.

You can read output before the subprocess terminates by setting the
pipe to be non-blocking:

import fcntl
import os
import subprocess

>>> process = subprocess.Popen("cat", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
>>> flags = fcntl.fcntl(process.stdout, fcntl.F_GETFL)
>>> fcntl.fcntl(process.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK)
0
>>> process.stdin.write('line1\n')
>>> process.stdout.read()
'line1\n'
>>> process.stdin.write('line2\n')
>>> process.stdout.read()
'line2\n'

Cheers,
Ian

Stephen Hansen

unread,
Jun 16, 2010, 5:30:46 PM6/16/10
to pytho...@python.org
On 6/16/10 1:29 PM, Brandon McGinty wrote:
> Both subprocess and os.popen* only allow inputput and output one time,
> and the output to be read only when the process terminates.

Its not that subprocess only *allow* input and output one at a time, but
that it a) provides blocking file objects by default, and b) those only
read until EOF.

It also provides *convenience* methods for the common case of writing
output once and receiving everything back, but that's not the only way
you can use it.

If you want a bidirectional write/read for awhile, you really just need
to switch those file objects to non-blocking and such.

I found this useful when I needed to do it:
http://code.activestate.com/recipes/440554/

--

Stephen Hansen
... Also: Ixokai
... Mail: me+list/python (AT) ixokai (DOT) io
... Blog: http://meh.ixokai.io/

signature.asc

Thomas Jollans

unread,
Jun 16, 2010, 5:37:25 PM6/16/10
to pytho...@python.org
On 06/16/2010 10:29 PM, Brandon McGinty wrote:
> All,
> I have researched this both in the python documentation, and via google.
> Neither subprocess nor os.popen* will do what I need.
> First, I would instanshiate an ongoing shell, that would remain active
> throughout the life of the socket connection.
> I am trying to take commands, coming in from a standard python socket,
> modify them, and then send them onto this shell, /bin/bash, for example.
> The output of these modified commands will be received from the shell,
> and sent back through the socket, possibly being modified further.
> The connection on the other end of the socket will send multiple
> commands, and will need output for each.
> Both subprocess and os.popen* only allow inputput and output one time,

Is that a fact?

Does this not work:

>>> from subprocess import Popen, PIPE
>>> cat = Popen(["cat"], stdin=PIPE, stdout=PIPE)
>>> cat.stdin.write("hello, world!\n")
>>> cat.stdout.readline()
'hello, world!\n'
>>> cat.stdin.write("and another line\n")
>>> cat.stdout.readline()
'and another line\n'
>>>


> and the output to be read only when the process terminates.

Brandon McGinty

unread,
Jun 16, 2010, 6:22:23 PM6/16/10
to Thomas Jollans
Ah. Thank you all for your quick responses. I shall implement
non-blocking stdin/stdout objects, then.

Thank You,
Brandon McGinty

Nobody

unread,
Jun 16, 2010, 8:37:44 PM6/16/10
to
On Wed, 16 Jun 2010 16:29:42 -0400, Brandon McGinty wrote:

> Both subprocess and os.popen* only allow inputput and output one time,
> and the output to be read only when the process terminates.

This is incorrect; you can read from and write to the pipe as you wish.
However: you may have problems if the child process buffers its output,
which is the default behaviour for stdout when it isn't associated with a
tty.

On Unix, you can get around this issue using the pty module. I don't know
about Windows; look into what "expect" uses.

0 new messages