Exécuter un programme externe (exécutable) en Python?

92

Je viens de commencer à travailler sur Python et j'ai essayé d'exécuter un exécutable externe à partir de Python.

J'ai un exécutable pour un programme écrit en Fortran. Disons que le nom de l'exécutable est flow.exe. Et mon exécutable se trouve dans C:\Documents and Settings\flow_model. J'ai essayé les commandes os.system et popen, mais jusqu'à présent, je n'ai pas pu le faire fonctionner. Le code suivant semble ouvrir la fenêtre de commande, mais il n'exécute pas le modèle.

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

Comment puis-je réparer cela?

Mesut
la source
2
Double

Réponses:

45

Ces espaces peuvent vraiment être un problème :-(. Essayez de os.chdir('C:/Documents\ and\ Settings/')suivre des chemins relatifs pour os.system, des subprocessméthodes, ou autre ...

Si les meilleurs efforts pour contourner l'obstacle des espaces dans le chemin continuent d'échouer, ma prochaine meilleure suggestion est d' éviter d' avoir des blancs dans vos chemins cruciaux. Ne pourriez-vous pas créer un répertoire sans espaces, y copier le .exefichier crucial et essayer cela ? Ces espaces dévastateurs sont-ils absolument essentiels à votre bien-être ...?

Alex Martelli
la source
1
Alex, merci. Cela a fonctionné aussi. J'ai encore une question si cela ne vous dérange pas. Et si mon exécutable demande le nom de mon fichier d'entrée? J'ai essayé de le faire en utilisant stdin mais je n'ai pas réussi jusqu'à présent?
Mesut
2
@mesut, qu'est-ce que cet exécutable utilise pour "demander" le nom du fichier? S'il s'agit de sa propre entrée standard, par exemple, vous pourrez peut-être l'utiliser subprocess.Popenpour y diriger les valeurs souhaitées. Si cela va plus loin (en utilisant l'entrée "console"), essayez wexpect, sage.math.washington.edu/home/goreckc/sage/wexpect .
Alex Martelli
le fichier d'entrée est un fichier .txt de base dans le même dossier. Le code ouvre maintenant l'exe à partir de la fenêtre cmd. Et l'exécutable demande le nom du fichier d'entrée. Existe-t-il un moyen de définir simplement ce nom (peut-être comme un chemin) dans le code? J'ai essayé subprocess.popen et j'ai essayé de regarder dans les variables. Je pensais que je pouvais utiliser stdin mais je n'ai pas vraiment fonctionné. J'apprécierais vraiment si vous pouviez me donner un exemple avec subprocess.popen avec l'exécutable situé dans C: \ flow_model, le nom de l'exécutable comme flow.exe et le nom du fichier d'entrée situé dans le même dossier que sac_bsl.txt
Mesut
La partie "demander le nom du fichier d'entrée" est celle qui pose problème. Ne rien savoir sur la façon dont cet exe est codé, comme je l'ai déjà mentionné, wexpectest la solution la plus probable, car elle vous permet de simuler exactement ce que ce fichier exe verrait lorsqu'il est appelé dans une fenêtre cmd.
Alex Martelli
42

Si vous utilisez Python 2.7 ou supérieur (en particulier avant Python 3.5), vous pouvez utiliser ce qui suit:

import subprocess
  • subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False) Exécute la commande décrite par args. Attend la fin de la commande, puis renvoie l'attribut returncode.
  • subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False) Exécute la commande avec des arguments. Attend la fin de la commande. Si le code de retour était zéro, retourne, sinon déclenche CalledProcessError. L'objet CalledProcessError aura le code de retour dans l'attribut returncode

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

Dans les chaînes Python normales, la combinaison de caractères \ U signale un échappement de point de code Unicode étendu.

Voici le lien vers la documentation: http://docs.python.org/3.2/library/subprocess.html

Pour Python 3.5+, vous pouvez désormais utiliser run () dans de nombreux cas: https://docs.python.org/3.5/library/subprocess.html#subprocess.run

Ida N
la source
7
Python 3.6.3 recommande run ()
Ricardo Zorio
33

Le moyen le plus simple est:

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

Ça marche; Je l'ai essayé.

Quelqu'un
la source
1
fonctionne correctement, mais existe-t-il un moyen d'ajouter des paramètres tels que -start et ainsi de suite?
Bassem Shahin
1
Ne fonctionne pas: module 'os' has no attribute 'startfile'. (Utilisation de python3.6)
not2qubit
Apparemment, ne fonctionne pas sur tout ce qui concerne Windows, contrairement à l'impression que donne la documentation .
not2qubit
24

J'essaierais d'insérer un «r» devant votre chemin si j'étais vous, pour indiquer que c'est une chaîne brute - et vous n'aurez pas à utiliser de barres obliques. Par exemple:

os.system(r"C:\Documents and Settings\flow_model\flow.exe")
Jon Mills
la source
19

Votre utilisation est correcte. Je parie que votre programme externe, flow.exe, doit être exécuté dans son répertoire, car il accède à certains fichiers externes qui y sont stockés.

Alors vous pourriez essayer:

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

(Méfiez-vous des guillemets doubles à l'intérieur des guillemets simples ...)

Adrien Plisson
la source
Fonctionne parfaitement, comment stocker les résultats directement dans un dataframe?
Sade
11

Utilisez un sous - processus , c'est un module plus petit donc il s'exécute le .exeplus rapidement.

import subprocess
subprocess.Popen([r"U:\Year 8\kerbal space program\KSP.exe"])
Frodon Baggins
la source
1
Tu veux dire que ça commence le .exeplus vite?
Peter Mortensen
7

En utilisant os.system :

import os
os.system(r'"C:/Documents and Settings/flow_model/flow.exe"')
Romy
la source
4

Essayer

import subprocess
subprocess.call(["C:/Documents and Settings/flow_model/flow.exe"])
int3
la source
essayé et la même chose s'est produite. il semble qu'il ouvre la fenêtre cmd mais alors il n'exécuterait pas l'exécutable. J'ai essayé l'exécutable séparément et cela fonctionne très bien. J'ai également déplacé le dossier en tant que C: / flow_model. Cela n'a pas fait de différence. ??
Mesut
2

Si c'était moi, je mettrais le fichier EXE dans le répertoire racine (C :) et verrais si cela fonctionne comme ça. Si tel est le cas, ce sont probablement les espaces (déjà mentionnés) dans le nom du répertoire. Sinon, il peut s'agir de certaines variables d'environnement.

Essayez également de vérifier votre stderr (en utilisant une réponse précédente par int3):

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

Le code n'est peut-être pas tout à fait correct car je n'utilise généralement pas Popen ou Windows, mais je devrais donner l'idée. Il se peut que le message d'erreur se trouve dans le flux d'erreur.

extraneon
la source
2
import os
path = "C:/Documents and Settings/flow_model/"
os.chdir(path)
os.system("flow.exe")
John
la source
1
Veuillez ajouter une explication de la raison pour laquelle votre code résout cette question.
rje
Cet article traite essentiellement le fichier * .exe en cours d'exécution comme vous le feriez avec le fichier Windows * .bat.
SamAct
2

en python 2.6, utilisez une chaîne entre guillemets "et apostrophe". Également un changement simple / en double //. Votre exemple de travail ressemblera à ceci:

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

Vous pouvez également utiliser tous les paramètres si votre programme les ingère.

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"')

Enfin, vous pouvez utiliser une variable de chaîne, comme un exemple de traçage en utilisant gnuplot directement à partir de 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)
Bomba Ps
la source
1

Est-ce que cela tente de s'exécuter C:\Documentsavec des arguments de "and", "Settings/flow_model/flow.exe"?

Aussi, vous pourriez envisager subprocess.call().

Thanatos
la source
0

C'est l'usage correct, mais peut-être que les espaces dans le nom du chemin gâchent les choses pour une raison quelconque.

Vous pouvez également exécuter le programme sous cmd.exe afin de voir toute sortie de flow.exe qui pourrait indiquer une erreur.

Dan Olson
la source
0

Il existe de nombreuses solutions différentes, et les résultats dépendront fortement de:

  • le système d'exploitation que vous utilisez: Windows, Cygwin, Linux, MacOS
  • la version de python que vous utilisez: Python2 ou Python3x

Comme j'ai découvert certaines choses qui sont censées fonctionner uniquement sous Windows, ce n'est probablement pas le cas, probablement parce que j'utilise Cygwin, qui déjoue la façon dont le système d'exploitation gère les chemins Windows. D'autres choses ne fonctionnent que dans les systèmes d'exploitation basés sur * nix purs ou en Python2 ou 3.

Voici mes conclusions:

  • De manière générale, os.system()c'est la méthode la plus indulgente.
  • os.startfile()est le moins indulgent. (Windows uniquement && si vous avez de la chance)
  • subprocess.Popen([...]) pas recommandé
  • subprocess.run(winView, shell=True) la manière recommandée!
  • Se souvenir que l'utilisation subprocessde n'importe quoi peut poser un risque pour la sécurité .

Essayez ceci:

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: Pourquoi voudriez-vous l'utiliser explorersous Windows?

R: Parce que si vous voulez simplement regarder les résultats d'un nouveau fichier, l'explorateur ouvrira automatiquement le fichier avec le programme Windows par défaut que vous avez défini pour ce type de fichier. Donc pas besoin de re-spécifier le programme par défaut à utiliser.

not2qubit
la source
0

pour la question ci-dessus, cette solution fonctionne.

changez simplement le chemin vers l'emplacement de votre fichier exécutable.

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")'''

Ici, test1.pdf rootimage est pour mon code.

Spurthi
la source
Avez - vous oublié une fermeture "en os.system?
Suraj Rao