Running a program from another program.
Laurent Verweijen
somelauw at gmail.com
Fri Jun 18 11:47:52 EDT 2010
Op donderdag 17-06-2010 om 15:16 uur [tijdzone -0700], schreef Stephen
Hansen:
> On 6/17/10 3:06 PM, Laurent Verweijen wrote:
> >>
> >> In your other thread you include an actual traceback:
> >>
> >> Traceback (most recent call last):
> >> File "subchronous_test.py", line 5, in <module>
> >> send_all(str(p), n)
> >> File "/home/Somelauw/asynchronous.py", line 145, in send_all
> >> while len(data):
> >> TypeError: object of type 'int' has no len()
> >>
> >> The first argumetn to send_all should be the actual Popen subclass. The
> >> second should be a string to send. I think that line really is intended
> >> to be:
> >>
> >> send_all(p, str(n)) # assuming 'n' is say, the number 5.
> >>
> >
> > You are right, I swapped the parameters, but even if I correct it, it
> > still gives the second error.
> >
>
> General rule of thumb: its best to never use the word "still" when it
> comes to debugging Python and exceptions, unless you are absolutely
> certain the exception is precisely the same.
>
> I don't doubt that you may still get an exception on send_all; but there
> is no way you're getting the *same* exception (that specific type error:
> attempting to call len() on an integer) if you corrected your arguments.
>
> You're getting the EOFError, because you're never sending anything to
> the subprocess. You're not getting anything from the subprocess because
> it never receives anything to send back. And apparently there's an error
> on send, which is causing that problem, but that error is...?
>
My last post, contains the output after I fixed swapping the parameters
and everything you said.
I think there is still a problem with output that gets blocked.
Couldn't it be just that the output which gets blocked is causing this
error?
Anyway here is the output again:
python subchronous_test.py
Traceback (most recent call last):
File "increment.py", line 8, in <module>
n = int(raw_input(str(n))) + 1
EOFError: EOF when reading a line
close failed in file object destructor:
Error in sys.excepthook:
Original exception was:
And here are all 3 files concatenated:
# subchronous_test
import sys
from asynchronous import *
p = Popen(["python", "increment.py"], stdin=PIPE, stdout=PIPE, stderr =
sys.stderr)
for n in [5, 7, 10, 4]:
send_all(p, str(n))
print(recv_some(p))
# increment.py
import sys, traceback
try:
n = 0
while True:
n = int(raw_input(str(n))) + 1
except:
print >>sys.stderr, traceback.format_exc()
# asynchronous.py
## {{{ http://code.activestate.com/recipes/440554/ (r10)
import os
import subprocess
import errno
import time
import sys
PIPE = subprocess.PIPE
if subprocess.mswindows:
from win32file import ReadFile, WriteFile
from win32pipe import PeekNamedPipe
import msvcrt
else:
import select
import fcntl
class Popen(subprocess.Popen):
def recv(self, maxsize=None):
return self._recv('stdout', maxsize)
def recv_err(self, maxsize=None):
return self._recv('stderr', maxsize)
def send_recv(self, input='', maxsize=None):
return self.send(input), self.recv(maxsize),
self.recv_err(maxsize)
def get_conn_maxsize(self, which, maxsize):
if maxsize is None:
maxsize = 1024
elif maxsize < 1:
maxsize = 1
return getattr(self, which), maxsize
def _close(self, which):
getattr(self, which).close()
setattr(self, which, None)
if subprocess.mswindows:
def send(self, input):
if not self.stdin:
return None
try:
x = msvcrt.get_osfhandle(self.stdin.fileno())
(errCode, written) = WriteFile(x, input)
except ValueError:
return self._close('stdin')
except (subprocess.pywintypes.error, Exception), why:
if why[0] in (109, errno.ESHUTDOWN):
return self._close('stdin')
raise
return written
def _recv(self, which, maxsize):
conn, maxsize = self.get_conn_maxsize(which, maxsize)
if conn is None:
return None
try:
x = msvcrt.get_osfhandle(conn.fileno())
(read, nAvail, nMessage) = PeekNamedPipe(x, 0)
if maxsize < nAvail:
nAvail = maxsize
if nAvail > 0:
(errCode, read) = ReadFile(x, nAvail, None)
except ValueError:
return self._close(which)
except (subprocess.pywintypes.error, Exception), why:
if why[0] in (109, errno.ESHUTDOWN):
return self._close(which)
raise
if self.universal_newlines:
read = self._translate_newlines(read)
return read
else:
def send(self, input):
if not self.stdin:
return None
if not select.select([], [self.stdin], [], 0)[1]:
return 0
try:
written = os.write(self.stdin.fileno(), input)
except OSError, why:
if why[0] == errno.EPIPE: #broken pipe
return self._close('stdin')
raise
return written
def _recv(self, which, maxsize):
conn, maxsize = self.get_conn_maxsize(which, maxsize)
if conn is None:
return None
flags = fcntl.fcntl(conn, fcntl.F_GETFL)
if not conn.closed:
fcntl.fcntl(conn, fcntl.F_SETFL, flags| os.O_NONBLOCK)
try:
if not select.select([conn], [], [], 0)[0]:
return ''
r = conn.read(maxsize)
if not r:
return self._close(which)
if self.universal_newlines:
r = self._translate_newlines(r)
return r
finally:
if not conn.closed:
fcntl.fcntl(conn, fcntl.F_SETFL, flags)
message = "Other end disconnected!"
def recv_some(p, t=.1, e=1, tr=5, stderr=0):
if tr < 1:
tr = 1
x = time.time()+t
y = []
r = ''
pr = p.recv
if stderr:
pr = p.recv_err
while time.time() < x or r:
r = pr()
if r is None:
if e:
raise Exception(message)
else:
break
elif r:
y.append(r)
else:
time.sleep(max((x-time.time())/tr, 0))
return ''.join(y)
def send_all(p, data):
while len(data):
sent = p.send(data)
if sent is None:
raise Exception(message)
data = buffer(data, sent)
if __name__ == '__main__':
if sys.platform == 'win32':
shell, commands, tail = ('cmd', ('dir /w', 'echo HELLO WORLD'),
'\r\n')
else:
shell, commands, tail = ('sh', ('ls', 'echo HELLO WORLD'), '\n')
a = Popen(shell, stdin=PIPE, stdout=PIPE)
print recv_some(a),
for cmd in commands:
send_all(a, cmd + tail)
print recv_some(a),
send_all(a, 'exit' + tail)
print recv_some(a, e=0)
a.wait()
## end of http://code.activestate.com/recipes/440554/ }}}
More information about the Python-list
mailing list