Jeremy Moles <je****@emperorlinux.comwrote:
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 <ni**@craig-wood.com--
http://www.craig-wood.com/nick