Running External Programs from Within Python

RayS rays at blue-cove.com
Tue Nov 30 19:37:25 EST 2004


At 10:50 PM 1/31/2004 +0100, Nuff Said wrote:
>On Sat, 31 Jan 2004 11:23:42 -0800, Bob=Moore wrote:

If anyone is interested, I used the following non-threaded code; I tried 
pipedream.py, but had apparent timing issues with the threads that I 
couldn't clear up.
I usually use wxPython. An *NIX version would be interesting as well (hint).
The external .exe is an interactive DOS-menu'd program in FORTRAN.

==================  snip  =============================

import os
import time
from wxPython.wx import *
import win32pipe


def getDataFrom(pipe):
     done = False
     timeout = 4 ## seconds
     start_time = time.time()
     data = ''
     error = None
     while not done:
         try:
             ## check to see if the 'file' has any data, using stat()
             #print os.fstat(input.fileno())[6],
             if(os.fstat(pipe.fileno())[6]!=0):
                 ## this will read up to a large amount
                 data = os.read(pipe.fileno(), 2**16)
             elif(len(data)):
                 ## if the read was done on the last loop, we can quit
                 done = True
                 #print 'read all'
             elif((time.time() - start_time) > timeout):
                 ## something went wrong
                 done = True
                 print 'Error; read timed out'
             else:
                 ## might be starting up the remote process...
                 time.sleep(.01)
         except (IOError, OSError):
             print '(IOError, OSError)',(IOError, OSError)
             done = True
     return [error, data]

def driveRemote(stdinput, stdoutput, resp):
     """ takes pipes and a string to send
         always gets the current DOS output first... """
     timeOut, result  = getDataFrom(stdoutput)
     if timeOut:
         print 'timedOut resp', result
         return timeOut

     print "remote:'%s'" % result[-60:],

     if (result==('' or None)):
         dlg = wxMessageDialog(parent, "resp not received!"+"\nGot 
'"+result+"'",
           'Error', wxOK | wxICON_INFORMATION)
         try:
             dlg.ShowModal()
         finally:
             dlg.Destroy()
         pgDlg.Destroy()

     ## check for errors
     if (string.find(result, 'run-time error')>-1):
         print resp, '\n'
         dlg = wxMessageDialog(None, result,
           'Error!', wxOK | wxICON_INFORMATION)
         try:
             dlg.ShowModal()
         finally:
             dlg.Destroy()
             return 'error: '+result

     if resp!=None:
         try:
             print resp, '\n'
             os.write(stdinput.fileno(), resp+'\n')
         except IOError, e:
             print 'error; resp, reslt:', resp, result
             print "IOError %s" % e
     return result

## actually start, text mode
stdinput, stdoutput = win32pipe.popen4("FV4R.EXE", 't')
## go through a list of actions
for resp in actionList:
     result = driveRemote(stdinput, stdoutput, resp)

================  snap  =======================

> > Can I run (call? exec? eval?) an external program from inside a Python
> > program?
> >
>
>Check out os.popen (in all it's variants); e.g. something like
>the following will do what you want:
>
>   import os
>
>   stdin, stdout, stderr = os.popen3('your program goes here')
>   output = stdout.read()
>   errors = stderr.read()
>   stdin.close(); stdout.close(); stderr.close()
>
>   ... do something with 'output' and 'errors' ...
>
>HTH / Nuff
>
>--
>http://mail.python.org/mailman/listinfo/python-list




More information about the Python-list mailing list