Eseguire un programma esterno (eseguibile) in Python?


92

Ho appena iniziato a lavorare su Python e ho provato a eseguire un eseguibile esterno da Python.

Ho un eseguibile per un programma scritto in Fortran. Supponiamo che il nome dell'eseguibile sia flow.exe. E il mio eseguibile si trova in C:\Documents and Settings\flow_model. Ho provato entrambi i comandi os.system e popen, ma finora non sono riuscito a farlo funzionare. Il codice seguente sembra che apra la finestra di comando, ma non eseguirà il modello.

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

Come posso risolvere questo problema?


2

Risposte:


45

Quegli spazi bianchi possono davvero essere un fastidio :-(. Prova os.chdir('C:/Documents\ and\ Settings/')seguito da percorsi relativi per os.system, subprocessmetodi o qualsiasi altra cosa ...

Se il miglior sforzo tenta di aggirare l'ostacolo degli spazi bianchi nel percorso continua a fallire, il mio prossimo miglior suggerimento è di evitare di avere spazi vuoti nei percorsi cruciali. Non potreste creare una directory spazi vuoti-less, copiare il cruciale .exefile di lì, e provare che ? Quegli spazi devastanti sono assolutamente essenziali per il tuo benessere ...?


1
Alex, grazie. Anche questo ha funzionato. Ho un'altra domanda se non ti dispiace. Che ne dici se il mio eseguibile chiede il nome del mio file di input? Ho provato a farlo usando stdin ma non ci sono riuscito finora?
Mesut

2
@mesut, qual è l'eseguibile che usa per "chiedere" il nome del file? Se è il proprio input standard, ad esempio, potresti essere in grado di utilizzare subprocess.Popenper reindirizzare i valori desiderati lì. Se va più in profondità (utilizzando l'input "console"), prova wexpect, sage.math.washington.edu/home/goreckc/sage/wexpect .
Alex Martelli

il file di input è un file .txt di base nella stessa cartella. Il codice in questo momento apre l'exe dalla finestra di cmd. E l'eseguibile chiede il nome del file di input. C'è un modo in cui posso definire questo nome (forse come un percorso) all'interno del codice? Ho provato subprocess.popen e ho provato a guardare nelle variabili. Ho pensato di poter usare stdin ma non ha funzionato davvero. Ti sarei davvero grato se puoi darmi un esempio con subprocess.popen con l'eseguibile situato in C: \ flow_model, il nome dell'eseguibile come flow.exe e il nome del file di input che si trova nella stessa cartella di sac_bsl.txt
Mesut

La parte "chiedi il nome del file di input" è quella problematica. Non sapere nulla su come è codificato quell'exe, come ho già detto, wexpectè la soluzione più probabile, in quanto ti consente di simulare esattamente ciò che vedrebbe quel file exe quando invocato in una finestra cmd.
Alex Martelli

42

Se si utilizza Python 2.7 o versioni successive (soprattutto prima di Python 3.5) è possibile utilizzare quanto segue:

import subprocess
  • subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False) Esegue il comando descritto da args. Attende il completamento del comando, quindi restituisce l'attributo returncode.
  • subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False) Esegue il comando con argomenti. Attende il completamento del comando. Se il codice di ritorno era zero, ritorna, altrimenti solleva CalledProcessError. L'oggetto CalledProcessError avrà il codice di ritorno nell'attributo returncode

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

Nelle normali stringhe Python, la combinazione di caratteri \ U segnala un escape del punto di codice Unicode esteso.

Ecco il collegamento alla documentazione: http://docs.python.org/3.2/library/subprocess.html

Per Python 3.5+ ora puoi usare run () in molti casi: https://docs.python.org/3.5/library/subprocess.html#subprocess.run


7
Python 3.6.3 consiglia run ()
Ricardo Zorio

33

Il modo più semplice è:

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

Funziona; L'ho provato.


1
funziona correttamente, ma c'è un modo per aggiungere parametri come -start e così via?
Bassem Shahin

1
Non funziona: module 'os' has no attribute 'startfile'. (Utilizzando python3.6)
not2qubit

Apparentemente non funziona su nulla di Windows, contrariamente all'impressione che dà la documentazione .
not2qubit

24

Proverei a inserire una "r" davanti al tuo percorso se fossi in te, per indicare che si tratta di una stringa grezza - e quindi non dovrai usare barre in avanti. Per esempio:

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

19

Il tuo utilizzo è corretto. Scommetto che il tuo programma esterno, flow.exe, deve essere eseguito nella sua directory, perché accede ad alcuni file esterni memorizzati lì.

Quindi potresti provare:

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

(Attenzione alle virgolette doppie all'interno delle virgolette singole ...)


Funziona perfettamente, come si memorizzano i risultati direttamente in un dataframe?
Sade

11

Usa sottoprocesso , è un modulo più piccolo quindi viene eseguito .exepiù velocemente.

import subprocess
subprocess.Popen([r"U:\Year 8\kerbal space program\KSP.exe"])

1
Vuoi dire che inizia il .exepiù veloce?
Peter Mortensen

7

Utilizzando os.system :

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

4

Provare

import subprocess
subprocess.call(["C:/Documents and Settings/flow_model/flow.exe"])

l'ho provato ed è successa la stessa cosa. sembra che apra la finestra cmd ma poi non eseguirà l'eseguibile. Ho provato l'eseguibile separatamente e funziona bene. Ho anche spostato la cartella come C: / flow_model. Non ha fatto differenza. ??
Mesut

2

Se fossi in me, metterei il file EXE nella directory principale (C :) e vedrei se funziona così. Se è così, probabilmente sono gli spazi (già menzionati) nel nome della directory. In caso contrario, potrebbero essere alcune variabili di ambiente.

Inoltre, prova a controllare il tuo stderr (usando una risposta precedente di int3):

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

Il codice potrebbe non essere del tutto corretto dato che di solito non uso Popen o Windows, ma dovrebbe dare l'idea. Potrebbe anche essere che il messaggio di errore si trovi nel flusso di errore.


2
import os
path = "C:/Documents and Settings/flow_model/"
os.chdir(path)
os.system("flow.exe")

1
Aggiungi una spiegazione del motivo per cui il tuo codice risolve questa domanda.
rje

Questo post tratta fondamentalmente il file * .exe in esecuzione come faresti con il file * .bat di Windows.
Sam,

2

in python 2.6 usa una stringa racchiusa tra virgolette "e segni di apostrofo. Anche un cambiamento da singolo / a doppio //. Il tuo esempio di lavoro sarà simile a questo:

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

Inoltre è possibile utilizzare qualsiasi parametro se il programma li ingerisce.

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 puoi usare la variabile stringa, come un esempio sta tracciando usando gnuplot direttamente da 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)

1

Sta cercando di eseguire C:\Documentscon argomenti di "and", "Settings/flow_model/flow.exe"?

Inoltre, potresti considerare subprocess.call().


0

Questo è l'uso corretto, ma forse gli spazi nel nome del percorso stanno rovinando le cose per qualche motivo.

Potresti voler eseguire il programma anche sotto cmd.exe in modo da poter vedere qualsiasi output da flow.exe che potrebbe indicare un errore.


0

Ci sono tantissime soluzioni diverse ei risultati dipenderanno fortemente da:

  • il sistema operativo in uso: Windows, Cygwin, Linux, MacOS
  • la versione di Python che stai utilizzando: Python2 o Python3x

Come ho scoperto alcune cose che si dice funzionino solo in Windows, non è così, probabilmente perché mi capita di usare Cygwin che sta superando in astuzia il modo in cui il sistema operativo gestisce i percorsi di Windows. Altre cose funzionano solo in sistemi operativi puri * nix o in Python2 o 3.

Ecco i miei risultati:

  • In generale, os.system()è il metodo più indulgente.
  • os.startfile()è il meno indulgente. (Solo Windows e & se sei fortunato)
  • subprocess.Popen([...]) non consigliato
  • subprocess.run(winView, shell=True) il modo consigliato!
  • Ricordare che l'utilizzo subprocessper qualsiasi cosa può rappresentare un rischio per la sicurezza .

Prova questi:

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)

D: Perché vorresti usare explorer in Windows?

A: Perché se vuoi solo guardare i risultati di qualche nuovo file, Explorer aprirà automaticamente il file con qualsiasi programma Windows predefinito che hai impostato per quel tipo di file. Quindi non è necessario specificare nuovamente il programma predefinito da utilizzare.


0

per la domanda precedente questa soluzione funziona.

basta cambiare il percorso in cui si trova il file eseguibile.

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

Qui test1.pdf rootimage è per il mio codice.


Avete dimenticato una chiusura "a os.system?
Suraj Rao
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.