Uruchamiasz zewnętrzny program (wykonywalny) w Pythonie?


92

Właśnie zacząłem pracować nad Pythonem i próbowałem uruchomić zewnętrzny plik wykonywalny z Pythona.

Mam plik wykonywalny programu napisanego w języku Fortran. Powiedzmy, że nazwa pliku wykonywalnego to flow.exe. Mój plik wykonywalny znajduje się w C:\Documents and Settings\flow_model. Wypróbowałem zarówno komendy os.system, jak i popen, ale do tej pory nie mogłem sprawić, by działało. Poniższy kod wydaje się otwierać okno poleceń, ale nie powodowałby wykonania modelu.

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

Jak mogę to naprawić?


Odpowiedzi:


44

Te białe spacje mogą być naprawdę kłopotliwe :-(. Spróbuj os.chdir('C:/Documents\ and\ Settings/')podążać za ścieżkami względnymi dla os.system, subprocessmetod lub cokolwiek ...

Jeśli najlepsze próby ominięcia przeszkód występujących w ścieżce wciąż kończą się niepowodzeniem, moja następna najlepsza sugestia to unikanie pustych miejsc na kluczowych ścieżkach. Nie mógłbyś stworzyć katalogu bez spacji, skopiować tam kluczowy .exeplik i spróbować tego ? Czy ta pustosząca spustoszenie przestrzeń jest absolutnie niezbędna dla Twojego dobrego samopoczucia ...?


1
Alex, dzięki. To też zadziałało. Mam jeszcze jedno pytanie, jeśli nie masz nic przeciwko. Co powiesz na to, że mój plik wykonywalny pyta o nazwę mojego pliku wejściowego? Próbowałem to zrobić za pomocą stdin, ale do tej pory nie udało mi się to zrobić?
Mesut

2
@mesut, czego ten plik wykonywalny używa do „pytania” o nazwę pliku? Na przykład, jeśli jest to własne standardowe wejście, możesz użyć subprocess.Popendo potokowania tam żądanych wartości. Jeśli idzie głębiej (używając wejścia "konsoli"), spróbuj wexpect, sage.math.washington.edu/home/goreckc/sage/wexpect .
Alex Martelli

plik wejściowy to podstawowy plik .txt w tym samym folderze. Kod w tej chwili otwiera plik exe z okna cmd. Plik wykonywalny pyta o nazwę pliku wejściowego. Czy istnieje sposób, w jaki mogę po prostu zdefiniować tę nazwę (może jako ścieżkę) w kodzie? Próbowałem subprocess.popen i próbowałem zajrzeć do zmiennych. Pomyślałem, że mogę użyć stdin, ale tak naprawdę nie wyszło. Byłbym naprawdę wdzięczny, gdybyś mógł dać mi próbkę z subprocess.popen z plikiem wykonywalnym znajdującym się w C: \ flow_model, nazwą pliku wykonywalnego jak flow.exe i nazwą pliku wejściowego znajdującego się w tym samym folderze co sac_bsl.txt
Mesut

Część „zapytaj o nazwę pliku wejściowego” jest kłopotliwa. Brak wiedzy o kodowaniu tego exe, jak już wspomniałem, wexpectjest najbardziej prawdopodobnym rozwiązaniem, ponieważ pozwala dokładnie zasymulować to, co zobaczyłby plik exe po wywołaniu w oknie cmd.
Alex Martelli

42

Jeśli korzystasz z Pythona 2.7 lub nowszego (zwłaszcza przed Pythonem 3.5), możesz użyć następujących:

import subprocess
  • subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False) Uruchamia polecenie opisane przez args. Czeka na zakończenie polecenia, a następnie zwraca atrybut powrotu.
  • subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False) Uruchamia polecenie z argumentami. Czeka na zakończenie polecenia. Jeśli kod powrotu był równy zero, to zwraca, w przeciwnym razie wywołuje CalledProcessError. Obiekt CalledProcessError będzie miał kod powrotu w atrybucie returncode

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

W zwykłych łańcuchach Pythona kombinacja znaków \ ​​U sygnalizuje rozszerzoną zmianę znaczenia punktu kodu Unicode.

Oto link do dokumentacji: http://docs.python.org/3.2/library/subprocess.html

W przypadku Pythona 3.5+ możesz teraz używać run () w wielu przypadkach: https://docs.python.org/3.5/library/subprocess.html#subprocess.run


7
Python 3.6.3 zaleca uruchomienie ()
Ricardo Zorio

34

Najprostszy sposób to:

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

To działa; Próbowałem tego.


1
działa poprawnie, ale czy istnieje sposób na dodanie parametrów, takich jak -start i tak dalej?
Bassem Shahin

1
Nie działa: module 'os' has no attribute 'startfile'. (Używając
Pythona3.6

Najwyraźniej nie działa na niczym związanym z Windows, wbrew wrażeniu, jakie daje dokumentacja .
not2qubit

Wydaje się, że działa tylko z ipythonem
user3273814

24

Na twoim miejscu spróbuję wstawić „r” przed twoją ścieżką, aby wskazać, że jest to nieprzetworzony ciąg - a wtedy nie będziesz musiał używać ukośników. Na przykład:

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

19

Twoje użycie jest prawidłowe. Założę się, że twój zewnętrzny program flow.exe musi zostać uruchomiony w swoim katalogu, ponieważ ma dostęp do plików zewnętrznych, które są tam przechowywane.

Możesz więc spróbować:

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

(Uważaj na podwójne cudzysłowy w pojedynczych cudzysłowach ...)


Działa doskonale, jak można przechowywać wyniki bezpośrednio w ramce danych?
Sade

11

Użyj podprocesu , jest to mniejszy moduł, więc działa .exeszybciej.

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

1
Masz na myśli to, że zaczyna się .exeszybciej?
Peter Mortensen

8

Korzystając z os.system :

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

4

Próbować

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

spróbowałem i stało się to samo. wygląda na to, że otwiera okno cmd, ale wtedy nie uruchomiłoby pliku wykonywalnego. Wypróbowałem plik wykonywalny osobno i działa dobrze. Przeniosłem również folder jako C: / flow_model. Nie zrobiło to różnicy. ??
Mesut

2

Gdybym to był ja, umieściłbym plik EXE w katalogu głównym (C :) i sprawdziłbym, czy to działa. Jeśli tak, to prawdopodobnie (już wspomniane) spacje w nazwie katalogu. Jeśli nie, może to być kilka zmiennych środowiskowych.

Spróbuj również sprawdzić, czy stderr (używając wcześniejszej odpowiedzi przez int3):

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

Kod może nie być całkowicie poprawny, ponieważ zwykle nie używam Popen ani Windows, ale powinienem dać pomysł. Może się zdarzyć, że komunikat o błędzie znajduje się w strumieniu błędów.


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

1
Dodaj wyjaśnienie, dlaczego Twój kod rozwiązuje to pytanie.
rje

Ten post zasadniczo traktuje plik * .exe, który jest wykonywany, tak jak w przypadku pliku Windows * .bat.
SamAct

2

w pythonie 2.6 użyj ciągu znaków w cudzysłowie "i apostrofów". Również zmiana pojedynczego / na podwójne //. Twój przykład roboczy będzie wyglądał następująco:

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

Możesz również użyć dowolnych parametrów, jeśli Twój program je pobiera.

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

na koniec możesz użyć zmiennej typu string, na przykład rysowanie za pomocą gnuplot bezpośrednio z Pythona:

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

Czy to jest próba wykonania C:\Documentsz argumentami "and", "Settings/flow_model/flow.exe"?

Możesz także rozważyć subprocess.call().


0

To prawidłowe użycie, ale być może spacje w nazwie ścieżki z jakiegoś powodu psują.

Możesz również chcieć uruchomić program pod cmd.exe, aby zobaczyć wszelkie dane wyjściowe z pliku flow.exe, które mogą wskazywać na błąd.


0

Istnieje wiele różnych rozwiązań, a wyniki będą w dużym stopniu zależały od:

  • używany system operacyjny : Windows, Cygwin, Linux, MacOS
  • używana wersja języka Python: Python2 lub Python3x

Ponieważ odkryłem, że niektóre rzeczy, o których twierdzi się, że działają tylko w systemie Windows, nie działają, prawdopodobnie dlatego, że używam Cygwin, który przechytrza sposób systemu operacyjnego, aby radzić sobie ze ścieżkami systemu Windows. Inne rzeczy działają tylko w systemach operacyjnych opartych na czystym * nix lub w Python2 lub 3.

Oto moje ustalenia:

  • Ogólnie rzecz biorąc, os.system()jest to najbardziej wybaczająca metoda.
  • os.startfile()jest najmniej wyrozumiały. (Tylko Windows &&, jeśli masz szczęście)
  • subprocess.Popen([...]) nie zalecane
  • subprocess.run(winView, shell=True) zalecany sposób!
  • Pamiętając, że używanie subprocessdo czegokolwiek może stanowić zagrożenie dla bezpieczeństwa .

Spróbuj tych:

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: Dlaczego chcesz używać explorerw systemie Windows?

Odp .: Ponieważ jeśli chcesz tylko spojrzeć na wyniki jakiegoś nowego pliku, eksplorator automatycznie otworzy plik za pomocą dowolnego domyślnego programu Windows, który ustawiłeś dla tego typu pliku. Nie ma więc potrzeby ponownego określania domyślnego programu do użycia.


0

na powyższe pytanie to rozwiązanie działa.

po prostu zmień ścieżkę do miejsca, w którym znajduje się plik wykonywalny.

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

Tutaj obraz główny test1.pdf jest dla mojego kodu.


Zapomniałeś o zamknięcie "w os.system?
Suraj Rao
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.