Jeremy Moles <[EMAIL PROTECTED]> wrote: > I'm not sure if this is really the right place to ask this question, but > since the implementation is in Python, I figured I'd give it a shot. > > I want to "wrap" a shell process using popen inside of python program > rather than creating a new shell process for each line I process in the > app. For example, the code might look like: > > > std = stdin, stdout, stderr = os.popen3("bash") > > print >> stdin, "ls" > > print stdout.readline() > > However, it appears my understanding of popen (or perhaps buffered IO) > is off somewhere, because this certainly doesn't work anything like I > expect it to (it hangs on stdout.readline). > > Obviously the example above is very contrived, but eventually I'll be > using this in an OpenGL "terminal" widget. Am I approaching this the > wrong way?
Short answer: use pexpect http://pexpect.sourceforge.net/ Long answer: Firstly modern pythonistas use subprocess instead of os.popen*. Secondly, buffering is going to cause you trouble and possible deadlocks. There are two ways to rid yourself of deadlock. 1) read and write from seperate threads / processes. This is the traditional unix way 2) use non blocking IO Here is a possible way to solve the problems with subprocess (unix only) and non blocking IO. However I suspect you really want to use pexpect for this job... from os import O_NONBLOCK from errno import EAGAIN from subprocess import Popen, PIPE from fcntl import fcntl, F_SETFL, F_GETFL from time import time p = Popen(["/bin/bash", "-i"], shell=False, bufsize=0, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True) # Make output streams non blocking (unix only) for fd in (p.stdout.fileno(), p.stderr.fileno()): fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK) def read_output(p, timeout=1.0): """Read the output from the subprocess, with timeout""" end_time = time() + timeout output = "" while time() < end_time: try: output += p.stdout.read(1024) except IOError, e: if e.errno != EAGAIN: raise return output p.stdin.write("ls\n") print read_output(p) p.stdin.write("uname -a\n") print read_output(p) -- Nick Craig-Wood <[EMAIL PROTECTED]> -- http://www.craig-wood.com/nick -- http://mail.python.org/mailman/listinfo/python-list