¿Ejecuta un programa externo (ejecutable) en Python?

92

Acabo de empezar a trabajar en Python y he estado intentando ejecutar un ejecutable externo desde Python.

Tengo un ejecutable para un programa escrito en Fortran. Digamos que el nombre del ejecutable es flow.exe. Y mi ejecutable se encuentra en C:\Documents and Settings\flow_model. Probé los comandos os.system y popen, pero hasta ahora no pude hacerlo funcionar. El siguiente código parece que abre la ventana de comandos, pero no ejecuta el modelo.

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

¿Cómo puedo arreglar esto?

Mesut
fuente
2
Posible duplicado de llamar a un comando externo en Python
mkobit

Respuestas:

45

Esos espacios en blanco puede realmente ser una molestia :-(. Trate os.chdir('C:/Documents\ and\ Settings/')seguido de rutas relativas para os.system, subprocessmétodos, o lo que sea ...

Si los intentos del mejor esfuerzo para evitar el obstáculo de los espacios en blanco en el camino siguen fallando, entonces mi siguiente mejor sugerencia es evitar tener espacios en blanco en sus caminos cruciales. ¿No podría hacer un directorio esbozos con menos, copie la clave .exearchivo, para tratar de que ? ¿Son esos espacios devastadores absolutamente esenciales para su bienestar ...?

Alex Martelli
fuente
1
Alex, gracias. Esto también funcionó. Tengo una pregunta más si no le importa. ¿Qué tal si mi ejecutable solicita el nombre de mi archivo de entrada? Intenté hacerlo usando stdin pero no pude hacerlo hasta ahora.
Mesut
2
@mesut, ¿qué usa ese ejecutable para "pedir" el nombre del archivo? Si es su propia entrada estándar, por ejemplo, es posible que pueda utilizar subprocess.Popenpara canalizar los valores deseados allí. Si va más profundo (usando la entrada de "consola"), intente wexpect, sage.math.washington.edu/home/goreckc/sage/wexpect .
Alex Martelli
el archivo de entrada es un archivo .txt básico en la misma carpeta. El código ahora abre el exe desde la ventana de cmd. Y el ejecutable solicita el nombre del archivo de entrada. ¿Hay alguna manera de que pueda definir este nombre (tal vez como una ruta) dentro del código? Probé subprocess.popen e intenté buscar en las variables. Pensé que podía usar stdin pero realmente no funcionó. Realmente agradecería si me pudiera dar una muestra con subprocess.popen con el ejecutable ubicado en C: \ flow_model, el nombre del ejecutable como flow.exe y el nombre del archivo de entrada ubicado en la misma carpeta que sac_bsl.txt
Mesut
La parte "pedir el nombre del archivo de entrada" es la más problemática. No saber nada sobre cómo se codifica wexpectese archivo exe , como ya mencioné, es la solución más probable, ya que le permite simular exactamente lo que vería ese archivo exe cuando se invoca en una ventana de cmd.
Alex Martelli
42

Si usa Python 2.7 o superior (especialmente antes de Python 3.5), puede usar lo siguiente:

import subprocess
  • subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False) Ejecuta el comando descrito por args. Espera a que se complete el comando y luego devuelve el atributo de código de retorno.
  • subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False) Ejecuta un comando con argumentos. Espera a que se complete el comando. Si el código de retorno fue cero, entonces regresa; de lo contrario, genera CalledProcessError. El objeto CalledProcessError tendrá el código de retorno en el atributo de código de retorno

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

En cadenas de Python normales, la combinación de caracteres \ U indica un escape de punto de código Unicode extendido.

Aquí está el enlace a la documentación: http://docs.python.org/3.2/library/subprocess.html

Para Python 3.5+, ahora puede usar run () en muchos casos: https://docs.python.org/3.5/library/subprocess.html#subprocess.run

Ida N
fuente
7
Python 3.6.3 recomienda ejecutar ()
Ricardo Zorio
33

La forma más sencilla es:

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

Funciona; Lo intenté.

Alguien
fuente
1
funcionando correctamente, pero ¿hay alguna forma de agregar parámetros como -start, etc.?
Bassem Shahin
1
No funciona: module 'os' has no attribute 'startfile'. (Usando python3.6)
not2qubit
Aparentemente no funciona en nada relacionado con Windows, contrariamente a la impresión que da la documentación .
not2qubit
24

Intentaría insertar una 'r' delante de su ruta si fuera usted, para indicar que es una cadena sin procesar, y luego no tendrá que usar barras diagonales. Por ejemplo:

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

Tu uso es correcto. Apuesto a que su programa externo, flow.exe, debe ejecutarse en su directorio, porque accede a algunos archivos externos almacenados allí.

Entonces podrías intentar:

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

(Tenga cuidado con las comillas dobles dentro de las comillas simples ...)

Adrien Plisson
fuente
Funciona perfectamente, ¿cómo se almacenarían los resultados directamente en un marco de datos?
Sade
11

Use subproceso , es un módulo más pequeño, por lo que se ejecuta .exemás rápido.

import subprocess
subprocess.Popen([r"U:\Year 8\kerbal space program\KSP.exe"])
Frodo Bolsón
fuente
1
¿Quiere decir que se inicia el .exemás rápido?
Peter Mortensen
7

Al usar os.system :

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

Tratar

import subprocess
subprocess.call(["C:/Documents and Settings/flow_model/flow.exe"])
int3
fuente
lo probé y sucedió lo mismo. parece que abre la ventana cmd pero luego no ejecutaría el ejecutable. Probé el ejecutable por separado y funciona bien. También moví la carpeta como C: / flow_model. No marcó la diferencia. ??
Mesut
2

Si fuera yo, pondría el archivo EXE en el directorio raíz (C :) y vería si funciona así. Si es así, probablemente sean los espacios (ya mencionados) en el nombre del directorio. Si no, pueden ser algunas variables de entorno.

Además, intente verificar su stderr (usando una respuesta anterior por int3):

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

Puede que el código no sea del todo correcto ya que normalmente no uso Popen o Windows, pero debería dar la idea. Es muy posible que el mensaje de error esté en la secuencia de errores.

extraneón
fuente
2
import os
path = "C:/Documents and Settings/flow_model/"
os.chdir(path)
os.system("flow.exe")
Juan
fuente
1
Agregue una explicación de por qué su código resuelve esta pregunta.
rje
Básicamente, esta publicación trata el archivo * .exe que se está ejecutando como lo haría con el archivo * .bat de Windows.
SamAct
2

en Python 2.6 use una cadena encerrada entre comillas "y apóstrofos '. También un cambio simple / a doble //. Su ejemplo de trabajo se verá así:

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

También puede utilizar cualquier parámetro si su programa los ingiere.

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

finalmente, puede usar una variable de cadena, como un ejemplo está trazando usando gnuplot directamente desde 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
fuente
1

¿Está intentando ejecutar C:\Documentscon argumentos de "and", "Settings/flow_model/flow.exe"?

Además, podría considerar subprocess.call().

Thanatos
fuente
0

Ese es el uso correcto, pero quizás los espacios en el nombre de la ruta están arruinando las cosas por alguna razón.

Es posible que también desee ejecutar el programa en cmd.exe para que pueda ver cualquier resultado de flow.exe que pueda estar indicando un error.

Dan Olson
fuente
0

Hay muchas soluciones diferentes y los resultados dependerán en gran medida de:

  • el sistema operativo que está utilizando: Windows, Cygwin, Linux, MacOS
  • la versión de Python que está utilizando: Python2 o Python3x

Como he descubierto algunas cosas que se dice que funcionan solo en Windows, no lo hace, probablemente porque uso Cygwin, que está superando la forma del sistema operativo para lidiar con las rutas de Windows. Otras cosas solo funcionan en sistemas operativos basados ​​en * nix puro o en Python2 o 3.

Aquí están mis hallazgos:

  • En general, os.system()es el método más indulgente.
  • os.startfile()es el que menos perdona. (Solo Windows && si tiene suerte)
  • subprocess.Popen([...]) no recomendado
  • subprocess.run(winView, shell=True) de la forma recomendada!
  • Recordar que usarlo subprocesspara cualquier cosa puede suponer un riesgo para la seguridad .

Prueba estos:

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)

P: ¿Por qué querrías usar explorer en Windows?

R: Porque si solo desea ver los resultados de algún archivo nuevo, el explorador abrirá automáticamente el archivo con cualquier programa de Windows predeterminado que haya configurado para ese tipo de archivo. Por tanto, no es necesario volver a especificar el programa predeterminado que se utilizará.

not2qubit
fuente
0

para la pregunta anterior, esta solución funciona.

simplemente cambie la ruta a donde se encuentra su archivo ejecutable.

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

Aquí test1.pdf rootimage es para mi código.

spurthi
fuente
¿Se le olvidó un cierre "en os.system?
Suraj Rao