Running an outside program (executable) in Python?
Asked Answered
N

15

123

I just started working on Python and have been trying to run an outside executable from Python.

I have an executable for a program written in Fortran. Let’s say the name for the executable is flow.exe, and my executable is located in C:\Documents and Settings\flow_model. I tried both os.system and popen commands, but so far, I couldn't make it work. The following code seems like it opens the command window, but it wouldn't execute the model.

# Import system modules
import sys, string, os, arcgisscripting
os.system("C:/Documents and Settings/flow_model/flow.exe")

How can I fix this?

Necrosis answered 28/11, 2009 at 5:36 Comment(2)
Possible duplicate of Calling an external command in PythonBillen
A) Don't use as an example, a program that nobody has. Use a program that everybody has e.g. C:\windows\system32\calc.exe or Chrome (which is in c:\program files..). B) If you tried running it from the cmd console (or an IDE's terminal eg VS Code's terminal) C:\blah>python blah.py<ENTER> you'd see it's pretty clear what is happening. 'C:/Documents' is not recognized as an internal or external command, operable program or batch file.Authorized
K
48

Those whitespaces can really be a bother. Try os.chdir('C:/Documents\ and\ Settings/') followed by relative paths for os.system, subprocess methods, or whatever...

If best-effort attempts to bypass the whitespaces-in-path hurdle keep failing, then my next best suggestion is to avoid having blanks in your crucial paths. Couldn't you make a blanks-less directory, copy the crucial .exe file there, and try that? Are those havoc-wrecking space absolutely essential to your well-being...?

Kyles answered 28/11, 2009 at 6:8 Comment(4)
Alex, thanks. This worked too. I have one more question if you dont mind. How about if my executable is asking for the name of my input file? I tried to do it using stdin but couldn't succeed so far?Necrosis
@mesut, what's that executable using to "ask for" the filename? If it's its own standard-input, for example, you might be able to use subprocess.Popen to pipe your desired values there. If it goes deeper (using "console" input), try wexpect, sage.math.washington.edu/home/goreckc/sage/wexpect .Kyles
the input file is a basic .txt file in the same folder. The code right now opens the exe from the cmd window. And the executable asks for the name of the input file. Is there a way that I can just define this name (maybe as a path) within the code? I tried subprocess.popen and I tried to look in the variables. I thought that I can use stdin but didnt really work out. I would really appreciate if you can give me a sample with subprocess.popen with the executable located in C:\flow_model, the name of the executable as flow.exe and name of the input file located in the same folder as sac_bsl.txtNecrosis
The "ask for the name of the input file" part is the troublesome one. Not knowing anything about how that exe is coded, as I already mentioned, wexpect is the likeliest solution, as it lets you simulate exactly what that exe file would see when invoked at a cmd window.Kyles
L
56

If using Python 2.7 or higher (especially prior to Python 3.5) you can use the following:

import subprocess
  • subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False) Runs the command described by args. Waits for command to complete, then returns the returncode attribute.
  • subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False) Runs command with arguments. Waits for command to complete. If the return code was zero then returns, otherwise raises CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute

Example: subprocess.check_call([r"C:\pathToYourProgram\yourProgram.exe", "your", "arguments", "comma", "separated"])

In regular Python strings, the \U character combination signals a extended Unicode code point escape.

Here is the link to the documentation: http://docs.python.org/3.2/library/subprocess.html

For Python 3.5+ you can now use run() in many cases: https://docs.python.org/3.5/library/subprocess.html#subprocess.run

Lalise answered 8/11, 2012 at 20:9 Comment(1)
Python 3.6.3 recommends run()Lanugo
L
50

The simplest way is:

import os
os.startfile("C:\Documents and Settings\flow_model\flow.exe")

It works; I tried it.

Lithotomy answered 1/5, 2012 at 8:17 Comment(3)
working properly, but is there a way to add parameters like -start and so on?Hasson
Doesn't work: module 'os' has no attribute 'startfile'. (Using python3.6)Stumer
Apparently doesn't work on anything Windows related, contrary to impression that the documentation gives.Stumer
K
48

Those whitespaces can really be a bother. Try os.chdir('C:/Documents\ and\ Settings/') followed by relative paths for os.system, subprocess methods, or whatever...

If best-effort attempts to bypass the whitespaces-in-path hurdle keep failing, then my next best suggestion is to avoid having blanks in your crucial paths. Couldn't you make a blanks-less directory, copy the crucial .exe file there, and try that? Are those havoc-wrecking space absolutely essential to your well-being...?

Kyles answered 28/11, 2009 at 6:8 Comment(4)
Alex, thanks. This worked too. I have one more question if you dont mind. How about if my executable is asking for the name of my input file? I tried to do it using stdin but couldn't succeed so far?Necrosis
@mesut, what's that executable using to "ask for" the filename? If it's its own standard-input, for example, you might be able to use subprocess.Popen to pipe your desired values there. If it goes deeper (using "console" input), try wexpect, sage.math.washington.edu/home/goreckc/sage/wexpect .Kyles
the input file is a basic .txt file in the same folder. The code right now opens the exe from the cmd window. And the executable asks for the name of the input file. Is there a way that I can just define this name (maybe as a path) within the code? I tried subprocess.popen and I tried to look in the variables. I thought that I can use stdin but didnt really work out. I would really appreciate if you can give me a sample with subprocess.popen with the executable located in C:\flow_model, the name of the executable as flow.exe and name of the input file located in the same folder as sac_bsl.txtNecrosis
The "ask for the name of the input file" part is the troublesome one. Not knowing anything about how that exe is coded, as I already mentioned, wexpect is the likeliest solution, as it lets you simulate exactly what that exe file would see when invoked at a cmd window.Kyles
E
30

I'd try inserting an 'r' in front of your path if I were you, to indicate that it's a raw string - and then you won't have to use forward slashes. For example:

os.system(r"C:\Documents and Settings\flow_model\flow.exe")
Exhibitionist answered 28/11, 2009 at 7:42 Comment(2)
The main issue here are the spaces inside, your suggestion is fine but not addressing the main issueTheseus
@FredianoZiglio you mean his suggestion won't workAuthorized
I
23

Your usage is correct. I bet that your external program, flow.exe, needs to be executed in its directory, because it accesses some external files stored there.

So you might try:

import sys, string, os, arcgisscripting
os.chdir('c:\\documents and settings\\flow_model')
os.system('"C:\\Documents and Settings\\flow_model\\flow.exe"')

(Beware of the double quotes inside the single quotes...)

Isham answered 28/11, 2009 at 9:8 Comment(5)
Works perfectly, how would one store the results directly to a dataframe?Malindamalinde
@Malindamalinde you aren't the OP. This solution won't work for the OP!Authorized
This won't work os.chdir('C:\\Program Files (x86)\\Google\\Chrome\\Application') and os.system('C:\\Program Files (x86)\\Google\\Chrome\\Application\chrome.exe') then 'C:\Program' is not recognized as an internal or external command, operable program or batch file.Authorized
@Authorized 1) thanks for reviving a 13 years old post 2) you are not the OP either, your comment is useless 3) what part of "Beware of the double quotes inside the single quotes" did you not understand ? the solution is explicit about that, yet you failed to implement it correctly and then complain that it does not work... so please learn to read first before making any useless comment !Isham
@AdrienPlisson I did miss what you did with the quotes.. I see now that it works with the doubles quotes inside the single quotes. As for your beware statement.. It'd be clearer if you wrote "Be aware of". 'cos "Beware" tends to precede some thing to not do. e.g. one would say "Beware of the unhealthy cake". One wouldn't say "Beware of the healthy food". And you could point to where the thing to Be aware of is.. as well as that it's necessary. "Be aware of the necessity of the single quotes around the double quotes, in that os.system command".Authorized
M
12

Use subprocess, it is a smaller module so it runs the .exe quicker.

import subprocess
subprocess.Popen([r"U:\Year 8\kerbal space program\KSP.exe"])
Mcneal answered 6/10, 2014 at 12:0 Comment(2)
You mean it starts the .exe quicker?Bosworth
OSError: [WinError 740] The requested operation requires elevationBellhop
A
9

By using os.system:

import os
os.system(r'"C:/Documents and Settings/flow_model/flow.exe"')
Abscise answered 16/10, 2014 at 20:51 Comment(0)
M
3

Try

import subprocess
subprocess.call(["C:/Documents and Settings/flow_model/flow.exe"])
Mishamishaan answered 28/11, 2009 at 5:39 Comment(1)
tried it and the same thing happened. it seems like it opens the cmd window but then it wouldnt run the executable. I tried the executable separately and it works fine. I also moved the folder as C:/flow_model. Didnt make a difference.??Necrosis
T
3

If it were me, I'd put the EXE file in the root directory (C:) and see if it works like that. If so, it's probably the (already mentioned) spaces in the directory name. If not, it may be some environment variables.

Also, try to check you stderr (using an earlier answer by int3):

import subprocess
process = subprocess.Popen(["C:/Documents and Settings/flow_model/flow.exe"], \
                           stderr = subprocess.PIPE)
if process.stderr:
    print process.stderr.readlines()

The code might not be entirely correct as I usually don't use Popen or Windows, but should give the idea. It might well be that the error message is on the error stream.

Theophany answered 28/11, 2009 at 11:43 Comment(0)
E
3
import os
path = "C:/Documents and Settings/flow_model/"
os.chdir(path)
os.system("flow.exe")

Note added by barlop

A commenter asked why this works. Here is why.

The OP's problem is os.system("...") doesn't work properly when there is a space in the path. (Note os.system can work with ('"...."') but anyhow)

Had the OP tried their program from a cmd prompt they'd have seen the error clearly.

    C:\carp>type blah.py
    import  os
    os.system(R"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe")
    
    C:\carp>python blah.py
    'C:\Program' is not recognized as an internal or external command,
    operable program or batch file.
    
    C:\carp>

So it's fine for os.system("calc.exe") (there calc.exe is in the path environment variable). Or for os.system(R"c:\windows\system32\calc.exe"). There's no space in that path.

C:\>md "aa bb cc"

C:\>copy c:\windows\system32\calc.exe "c:\aa bb cc\cccalc.exe"
        1 file(s) copied.

This works (Given file "c:\aa bb cc\cccalc.exe" )

import  os 
os.chdir(R"c:\aa bb cc")
os.system("cccalc.exe")

Other options are subprocess.run and subprocess.popen.

Edholm answered 15/10, 2018 at 21:36 Comment(4)
Please add an explanation of why your code solves this question.Labyrinth
This post is basically treating the *.exe file being executed as you would using windows *.bat file.Heart
@Heart no, that is gibberish.Authorized
@Labyrinth I've added to his answer on why his solution worksAuthorized
C
2

in python 2.6 use string enclosed inside quotation " and apostrophe ' marks. Also a change single / to double //. Your working example will look like this:

import os
os.system("'C://Documents and Settings//flow_model//flow.exe'") 

Also You can use any parameters if Your program ingest them.

os.system('C://"Program Files (x86)"//Maxima-gcl-5.37.3//gnuplot//bin//gnuplot -e "plot [-10:10] sin(x),atan(x),cos(atan(x)); pause mouse"')

finally You can use string variable, as an example is plotting using gnuplot directly from python:

this_program='C://"Program Files (x86)"//Maxima-gcl-5.37.3//gnuplot//bin//gnuplot'

this_par='-e "set polar; plot [-2*pi:2*pi] [-3:3] [-3:3] t*sin(t); pause -1"'
os.system(this_program+" "+this_par)
Creodont answered 25/1, 2019 at 5:57 Comment(0)
I
1

Is that trying to execute C:\Documents with arguments of "and", "Settings/flow_model/flow.exe"?

Also, you might consider subprocess.call().

Ineligible answered 28/11, 2009 at 5:39 Comment(0)
S
1

There are loads of different solutions, and the results will strongly depend on:

  • the OS you are using: Windows, Cygwin, Linux, MacOS
  • the python version you are using: Python2 or Python3x

As I have discovered some things that are claimed to work only in Windows, doesn't, probably because I happen to use Cygwin which is outsmarting the OS way to deal with Windows paths. Other things only work in pure *nix based OS's or in Python2 or 3.

Here are my findings:

  • Generally speaking, os.system() is the most forgiving method.
  • os.startfile() is the least forgiving. (Windows only && if you're lucky)
  • subprocess.Popen([...]) not recommended
  • subprocess.run(winView, shell=True) the recommended way!
  • Remembering that using subprocess for anything may pose a security risk.

Try these:

import os, subprocess
...
winView = '/cygdrive/c/Windows/explorer.exe %s' % somefile
...
# chose one of these:
os.system(winView)
subprocess.Popen(['/cygdrive/c/Windows/explorer.exe', 'somefile.png'])
subprocess.run(winView, shell=True)

Q: Why would you want to use explorer in Windows?

A: Because if you just want to look at the results of some new file, explorer will automatically open the file with whatever default windows program you have set for that file type. So no need to re-specify the default program to use.

Stumer answered 3/11, 2018 at 2:53 Comment(1)
cygwin is not an operating system!!!Authorized
F
0

That's the correct usage, but perhaps the spaces in the path name are messing things up for some reason.

You may want to run the program under cmd.exe as well so you can see any output from flow.exe that might be indicating an error.

Foulmouthed answered 28/11, 2009 at 5:40 Comment(0)
A
0

for the above question this solution works.

just change the path to where your executable file is located.

import sys, string, os

os.chdir('C:\\Downloads\\xpdf-tools-win-4.00\\xpdf-tools-win-4.00\\bin64')

os.system("C:\\Downloads\\xpdf-tools-win-4.00\\xpdf-tools-win-4.00\bin64\\flowwork.exe")


'''import sys, string, os

os.chdir('C:\\Downloads\\xpdf-tools-win-4.00\\xpdf-tools-win-4.00\\bin64')

os.system(r"C:\\Downloads\\xpdf-tools-win-4.00\\xpdf-tools-win-4.00\bin64\\pdftopng.exe test1.pdf rootimage")'''

Here test1.pdf rootimage is for my code .

Alas answered 16/8, 2018 at 5:34 Comment(1)
Did you forget a closing " in os.system?Foumart

© 2022 - 2024 — McMap. All rights reserved.