Discussion:
Running External Programs from Within Python
(too old to reply)
Bob=Moore
2004-01-31 19:23:42 UTC
Permalink
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
Dirk Hagemann
2004-01-31 20:20:15 UTC
Permalink
Post by 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
Hi Bob!

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

Regards
Dirk
Nuff Said
2004-01-31 21:50:52 UTC
Permalink
Post by Bob=Moore
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
RayS
2004-01-31 21:19:17 UTC
Permalink
Hi Dirk,
Post by Dirk Hagemann
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
Dirk Hagemann
2004-01-31 22:56:25 UTC
Permalink
Post by RayS
Hi Dirk,
Post by Dirk Hagemann
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
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
Cameron Laird
2004-02-01 05:46:12 UTC
Permalink
Post by Dirk Hagemann
Post by RayS
Hi Dirk,
Post by Dirk Hagemann
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
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?
--
Cameron Laird <***@phaseit.net>
Business: http://www.Phaseit.net
RayS
2004-02-01 09:48:33 UTC
Permalink
Hi Cameron,
Post by Cameron Laird
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...
Post by 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.

Ray
Cameron Laird
2004-02-01 15:47:23 UTC
Permalink
In article <mailman.1093.1075628924.12720.python-***@python.org>,
RayS <***@blue-cove.com> wrote:
.
.
.
Post by RayS
Post by 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.
--
Cameron Laird <***@phaseit.net>
Business: http://www.Phaseit.net
Ray S
2004-09-21 22:36:42 UTC
Permalink
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
David Dürrenmatt
2004-01-31 21:47:47 UTC
Permalink
Post by Bob=Moore
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
RayS
2004-12-01 00:37:25 UTC
Permalink
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 =======================
Post by Nuff Said
Post by Bob=Moore
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
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
Continue reading on narkive:
Loading...