Menjalankan program luar (dapat dieksekusi) dengan Python?

92

Saya baru saja mulai mengerjakan Python, dan saya telah mencoba menjalankan executable luar dari Python.

Saya memiliki program yang dapat dieksekusi yang ditulis di Fortran. Misalkan nama untuk executable adalah flow.exe. Dan executable saya terletak di C:\Documents and Settings\flow_model. Saya mencoba perintah os.system dan popen, tetapi sejauh ini saya tidak dapat membuatnya berfungsi. Kode berikut sepertinya membuka jendela perintah, tetapi tidak akan menjalankan model.

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

Bagaimana cara memperbaikinya?

Mesut
sumber
2
Kemungkinan duplikat dari Memanggil perintah eksternal dengan Python
mkobit

Jawaban:

44

Spasi putih itu benar-benar bisa mengganggu :-(. Coba os.chdir('C:/Documents\ and\ Settings/')ikuti jalur relatif untuk os.system, subprocessmetode, atau apa pun ...

Jika upaya terbaik untuk melewati rintangan whitespaces-in-path terus gagal, maka saran terbaik saya berikutnya adalah menghindari kekosongan di jalur penting Anda. Tidak bisa Anda buat direktori kosong-kurang, menyalin penting .exeberkas sana, dan mencoba yang ? Apakah ruang penghancur malapetaka itu benar-benar penting untuk kesejahteraan Anda ...?

Alex Martelli
sumber
1
Alex, terima kasih. Ini juga berhasil. Saya punya satu pertanyaan lagi jika Anda tidak keberatan. Bagaimana jika executable saya menanyakan nama file input saya? Saya mencoba melakukannya menggunakan stdin tetapi sejauh ini tidak berhasil?
Mesut
2
@ Mesut, apa yang dapat dieksekusi menggunakan untuk "meminta" nama file? Jika itu adalah input standarnya sendiri, misalnya, Anda mungkin dapat menggunakan subprocess.Popenuntuk menyalurkan nilai yang Anda inginkan di sana. Jika lebih dalam (menggunakan input "konsol"), coba wexpect, sage.math.washington.edu/home/goreckc/sage/wexpect .
Alex Martelli
file masukan adalah file .txt dasar di folder yang sama. Kode sekarang membuka exe dari jendela cmd. Dan file yang dapat dieksekusi meminta nama file input. Apakah ada cara agar saya bisa mendefinisikan nama ini (mungkin sebagai jalur) di dalam kode? Saya mencoba subprocess.popen dan saya mencoba mencari di variabel. Saya pikir saya bisa menggunakan stdin tetapi tidak benar-benar berhasil. Saya akan sangat menghargai jika Anda dapat memberi saya sampel dengan subprocess.popen dengan file yang dapat dieksekusi terletak di C: \ flow_model, nama yang dapat dieksekusi sebagai flow.exe dan nama file input yang terletak di folder yang sama dengan sac_bsl.txt
Mesut
Bagian "minta nama file input" adalah yang merepotkan. Tidak tahu apa-apa tentang bagaimana exe itu dikodekan, seperti yang telah saya sebutkan, wexpectadalah solusi yang paling mungkin, karena memungkinkan Anda mensimulasikan dengan tepat apa yang akan dilihat file exe itu ketika dipanggil di jendela cmd.
Alex Martelli
42

Jika menggunakan Python 2.7 atau lebih tinggi (terutama sebelum Python 3.5) Anda dapat menggunakan yang berikut ini:

import subprocess
  • subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False) Menjalankan perintah yang dijelaskan oleh args. Menunggu perintah selesai, lalu mengembalikan atribut kode kembali.
  • subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False) Menjalankan perintah dengan argumen. Menunggu perintah selesai. Jika kode kembali adalah nol maka kembali, jika tidak memunculkan CalledProcessError. Objek CalledProcessError akan memiliki kode pengembalian dalam atribut kode kembali

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

Dalam string Python biasa, kombinasi karakter \ U menandakan pelarian titik kode Unicode yang diperluas.

Berikut ini tautan ke dokumentasi: http://docs.python.org/3.2/library/subprocess.html

Untuk Python 3.5+, Anda sekarang dapat menggunakan run () dalam banyak kasus: https://docs.python.org/3.5/library/subprocess.html#subprocess.run

Ida N
sumber
7
Python 3.6.3 merekomendasikan run ()
Ricardo Zorio
34

Cara yang paling sederhana adalah:

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

Berhasil; Saya mencobanya.

Some one
sumber
1
berfungsi dengan baik, tetapi apakah ada cara untuk menambahkan parameter seperti -mulai dan seterusnya?
Bassem Shahin
1
Tidak bekerja: module 'os' has no attribute 'startfile'. (Menggunakan python3.6)
not2qubit
Rupanya tidak berfungsi pada apa pun yang berhubungan dengan Windows, bertentangan dengan kesan yang diberikan dokumentasi .
not2qubit
Sepertinya hanya bekerja dengan
ipython
24

Saya akan mencoba memasukkan 'r' di depan jalan Anda jika saya jadi Anda, untuk menunjukkan bahwa itu adalah string mentah - dan kemudian Anda tidak perlu menggunakan garis miring ke depan. Sebagai contoh:

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

Penggunaan Anda benar. Saya yakin program eksternal Anda, flow.exe, perlu dijalankan di direktorinya, karena ia mengakses beberapa file eksternal yang disimpan di sana.

Jadi Anda bisa mencoba:

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

(Waspadalah terhadap tanda kutip ganda di dalam tanda kutip tunggal ...)

Adrien Plisson
sumber
Bekerja dengan sempurna, bagaimana cara menyimpan hasil langsung ke dataframe?
Sade
11

Gunakan subproses , ini adalah modul yang lebih kecil sehingga berjalan .exelebih cepat.

import subprocess
subprocess.Popen([r"U:\Year 8\kerbal space program\KSP.exe"])
Frodo Baggins
sumber
1
Anda berarti itu dimulai dengan .execepat?
Peter Mortensen
8

Dengan menggunakan os.system :

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

Mencoba

import subprocess
subprocess.call(["C:/Documents and Settings/flow_model/flow.exe"])
int3
sumber
mencobanya dan hal yang sama terjadi. Sepertinya itu membuka jendela cmd tetapi kemudian itu tidak akan menjalankan eksekusi. Saya mencoba eksekusi secara terpisah dan berfungsi dengan baik. Saya juga memindahkan folder sebagai C: / flow_model. Tidak membuat perbedaan. ??
Mesut
2

Jika itu saya, saya akan meletakkan file EXE di direktori root (C :) dan melihat apakah berfungsi seperti itu. Jika demikian, mungkin itu adalah spasi (yang telah disebutkan) di nama direktori. Jika tidak, mungkin ada beberapa variabel lingkungan.

Juga, coba periksa Anda stderr (menggunakan jawaban sebelumnya oleh int3):

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

Kode mungkin tidak sepenuhnya benar karena saya biasanya tidak menggunakan Popen atau Windows, tetapi saya harus memberikan ide. Mungkin saja pesan kesalahan ada di aliran kesalahan.

extraneon
sumber
2
import os
path = "C:/Documents and Settings/flow_model/"
os.chdir(path)
os.system("flow.exe")
John
sumber
1
Tambahkan penjelasan tentang mengapa kode Anda menjawab pertanyaan ini.
rje
Posting ini pada dasarnya memperlakukan file * .exe yang dieksekusi seperti yang Anda lakukan menggunakan file windows * .bat.
SamAct
2

di python 2.6 gunakan string yang diapit di dalam tanda kutip "dan tanda kutip. Juga ubah satu / menjadi ganda //. Contoh kerja Anda akan terlihat seperti ini:

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

Anda juga dapat menggunakan parameter apa pun jika program Anda menyerapnya.

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

terakhir Anda dapat menggunakan variabel string, sebagai contoh adalah merencanakan menggunakan gnuplot langsung dari 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
sumber
1

Apakah itu mencoba untuk dieksekusi C:\Documentsdengan argumen "and", "Settings/flow_model/flow.exe"?

Juga, Anda mungkin mempertimbangkan subprocess.call().

Thanatos
sumber
0

Itu penggunaan yang benar, tapi mungkin spasi di nama jalur mengacaukan karena suatu alasan.

Anda mungkin ingin menjalankan program di bawah cmd.exe juga sehingga Anda dapat melihat keluaran apa pun dari flow.exe yang mungkin menunjukkan kesalahan.

Dan Olson
sumber
0

Ada banyak solusi berbeda, dan hasilnya akan sangat bergantung pada:

  • OS yang Anda gunakan: Windows, Cygwin, Linux, MacOS
  • versi python yang Anda gunakan: Python2 atau Python3x

Karena saya telah menemukan beberapa hal yang diklaim hanya berfungsi di Windows, tidak, mungkin karena saya kebetulan menggunakan Cygwin yang mengakali cara OS untuk menangani jalur Windows. Hal-hal lain hanya bekerja di OS berbasis * nix murni atau di Python2 atau 3.

Inilah temuan saya:

  • Secara umum, os.system()adalah metode paling pemaaf.
  • os.startfile()adalah yang paling pemaaf. (Khusus Windows && jika Anda beruntung)
  • subprocess.Popen([...]) tidak direkomendasikan
  • subprocess.run(winView, shell=True) cara yang direkomendasikan!
  • Mengingat bahwa menggunakan subprocessuntuk apa pun dapat menimbulkan risiko keamanan .

Coba ini:

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)

T: Mengapa Anda ingin menggunakan explorer di Windows?

A: Karena jika Anda hanya ingin melihat hasil dari beberapa file baru, explorer akan secara otomatis membuka file tersebut dengan program windows default apa pun yang telah Anda setel untuk jenis file tersebut. Jadi tidak perlu menentukan ulang program default yang akan digunakan.

not2qubit
sumber
0

untuk pertanyaan di atas, solusi ini berfungsi.

cukup ubah jalur ke tempat file yang dapat dieksekusi berada.

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

Di sini rootimage test1.pdf adalah untuk kode saya.

spurthi
sumber
Apakah Anda lupa penutup "di os.system?
Suraj Rao