Running External Programs from Within Python

B

Bob=Moore

I'm considering making the transfer from Rexx to Python as a scripting
language, but there's one thing I can do in Rexx that I can't seem to
do in Python: run an external program.

Suppose I have a Tkinter GUI and I want to just push a button and run
the Windows utility notepad.exe. Or push another button and run one
of my old Rexx programs.

Basically I want to send a command line to Python and have it run that
command line as if I'm sending it to the Windows command-prompt, an
MS-DOS window, or clicking on an appropriate program icon.

Can I run (call? exec? eval?) an external program from inside a Python
program?

I have checked the FAQ and documentation.

Thanx,

Bob=Moore
 
D

Dirk Hagemann

Bob=Moore said:
I'm considering making the transfer from Rexx to Python as a scripting
language, but there's one thing I can do in Rexx that I can't seem to
do in Python: run an external program.

Suppose I have a Tkinter GUI and I want to just push a button and run
the Windows utility notepad.exe. Or push another button and run one
of my old Rexx programs.

Basically I want to send a command line to Python and have it run that
command line as if I'm sending it to the Windows command-prompt, an
MS-DOS window, or clicking on an appropriate program icon.

Can I run (call? exec? eval?) an external program from inside a Python
program?

I have checked the FAQ and documentation.

Thanx,

Bob=Moore

Hi Bob!

That is very easy: popen()
Check the FAQ and documentation again for popen.

Regards
Dirk
 
R

RayS

Hi Dirk,
That is very easy: popen()
Check the FAQ and documentation again for popen.

That reminds me, I was asked if you can open a bi-directional pipe to
control an external console program on Windows. A guy has compiled FORTRAN
(~4,000 lines of 1980's spaghetti) and wants to add a modern GUI and a
front end method to check data.
Can you both send commands to, and read STDOUT from, a remote console app?

Ray
 
?

=?iso-8859-15?Q?David_D=FCrrenmatt?=

Can I run (call? exec? eval?) an external program from inside a Python
program?

Try this:

import os
os.system('notepad.exe') # starts notepad

For complex interaction, use win32pipe (Win32 Extensions).


dave
 
N

Nuff Said

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
 
D

Dirk Hagemann

RayS said:
Hi Dirk,



That reminds me, I was asked if you can open a bi-directional pipe to
control an external console program on Windows. A guy has compiled
FORTRAN (~4,000 lines of 1980's spaghetti) and wants to add a modern GUI
and a front end method to check data.
Can you both send commands to, and read STDOUT from, a remote console app?

Ray
I'm not sure if I got the point, but, for example, with popen I can ping
from the console a computer and read the result.
But sending commands to a remote console is a problem which troubles
myself in another context (I asked here yesterday).

Dirk
 
C

Cameron Laird

I'm not sure if I got the point, but, for example, with popen I can ping
from the console a computer and read the result.
But sending commands to a remote console is a problem which troubles
myself in another context (I asked here yesterday).

Dirk

The answer is, yes, you can do what you want--assuming that
"remote" means something different to you than the way the
rest of us are reading it.

The kind of wrapping you're describing is a VERY common use
of Python. Before we provide more details, though, you go
first; specifically, are you thinking of your bi-directional
pipe as a batch operation, or a programmatic one? Do you
know at the time you launch the Fortran-coded application
all the input it'll need?
 
R

RayS

Hi Cameron,
Before we provide more details, though, you go
first; specifically, are you thinking of your bi-directional
pipe as a batch operation, or a programmatic one?
Interactive/programmatic...

Do you
know at the time you launch the Fortran-coded application
all the input it'll need?

Usually not. It's a balance solution routine that requires some interaction
from the engineers; the Fortran has a three layer menu, and produces both
screen output and files. There is an intermediary result which has to be
looked at by the user to decide on the final balance, otherwise I would
change the code to just run from arg[] values.
One of its problems is that there is minimal error checking, and a bad
input requires the user to start over!
From the popen() docs, it seemed as though Windows could not have both
read and write ability over a pipe.

Ray
 
C

Cameron Laird

.
.
.
Do you
know at the time you launch the Fortran-coded application
all the input it'll need?

Usually not. It's a balance solution routine that requires some interaction
from the engineers; the Fortran has a three layer menu, and produces both
screen output and files. There is an intermediary result which has to be
looked at by the user to decide on the final balance, otherwise I would
change the code to just run from arg[] values.
One of its problems is that there is minimal error checking, and a bad
input requires the user to start over!
From the popen() docs, it seemed as though Windows could not have both
read and write ability over a pipe.
.
.
.
Right. What you probably want is os.popen2(), which
<URL: http://python.org/doc/current/lib/module-popen2.html >
documents. popen() is *not* adequate to your situation.

I write "probably" above only because your description doesn't
make clear to me whether you need your Fortran process's stderr.
If you do, then read through that same reference page to study
popen3() and popen4().

Keep in mind that you're doing something at which Python is
quite apt. This kind of wrapping can be fun. You'll be suc-
cessful.
 
R

Ray S

Does anyone know why a script that uses win32pipe.popen3() will run a
script, but hang when compiled?

I can't get a script that uses pipedream.py to run when compiled with
McMillan or py2exe; it appears that the client process (an interactive DOS
exe) returns the first screen of text, gets to its first prompt, then exits.

pipedream.py does: c = os.read(self._in.fileno(), 1) and just hangs, no error.

I'd appreciate any and all tips ...

Ray Schumacher
Blue Cove Interactive
7220 Trade Street, Suite 101
San Diego, CA 92121
858.695.8801
http://Blue-Cove.com
 
R

RayS

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 =======================
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,737
Latest member
Georgeengab

Latest Threads

Top