เรียกใช้โปรแกรมภายนอก (ปฏิบัติการ) ใน Python?


92

ฉันเพิ่งเริ่มทำงานกับ Python และฉันพยายามเรียกใช้ไฟล์ปฏิบัติการภายนอกจาก Python

ฉันมีไฟล์ปฏิบัติการสำหรับโปรแกรมที่เขียนใน Fortran สมมติว่าชื่อของไฟล์ปฏิบัติการคือ flow.exe และไฟล์ปฏิบัติการของฉันอยู่ในC:\Documents and Settings\flow_model. ฉันลองทั้งคำสั่ง os.system และ popen แต่จนถึงตอนนี้ฉันไม่สามารถใช้งานได้ ดูเหมือนว่าโค้ดต่อไปนี้จะเปิดหน้าต่างคำสั่ง แต่จะไม่เรียกใช้โมเดล

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

ฉันจะแก้ไขปัญหานี้ได้อย่างไร?


คำตอบ:


44

ช่องว่างเหล่านั้นจริงๆสามารถรำคาญ :-(. พยายามที่จะos.chdir('C:/Documents\ and\ Settings/')ตามมาด้วยเส้นทางญาติos.system, subprocessวิธีการหรืออะไรก็ตาม ...

หากความพยายามอย่างเต็มที่ที่จะหลีกเลี่ยงอุปสรรคในช่องว่างในเส้นทางยังคงล้มเหลวคำแนะนำที่ดีที่สุดต่อไปของฉันคือหลีกเลี่ยงการมีช่องว่างในเส้นทางที่สำคัญของคุณ ไม่สามารถให้คุณไดเรกทอรีช่องว่างน้อยคัดลอกสำคัญ.exeไฟล์ที่นั่นและพยายามที่ ? พื้นที่ทำลายล้างเหล่านั้นจำเป็นอย่างยิ่งต่อความเป็นอยู่ของคุณ ... ?


1
อเล็กซ์ขอบคุณ นี้ได้ผลเกินไป ฉันมีอีกหนึ่งคำถามถ้าคุณไม่รังเกียจ ถ้าไฟล์ปฏิบัติการของฉันถามชื่อไฟล์อินพุตของฉันได้อย่างไร? ฉันพยายามทำโดยใช้ stdin แต่ยังไม่ประสบความสำเร็จ?
Mesut

2
@mesut ไฟล์ปฏิบัติการที่ใช้ "ขอ" ชื่อไฟล์คืออะไร ตัวอย่างเช่นหากเป็นอินพุตมาตรฐานของตัวเองคุณอาจสามารถใช้subprocess.Popenกำหนดค่าที่ต้องการได้ที่นั่น ถ้าจะไปลึก (โดยใช้ "คอนโซล" การป้อนข้อมูล) ลอง wexpect, sage.math.washington.edu/home/goreckc/sage/wexpect
Alex Martelli

ไฟล์อินพุตเป็นไฟล์. txt พื้นฐานในโฟลเดอร์เดียวกัน ตอนนี้โค้ดจะเปิด exe จากหน้าต่าง cmd และไฟล์ปฏิบัติการจะถามชื่อของไฟล์อินพุต มีวิธีที่ฉันสามารถกำหนดชื่อนี้ (อาจเป็นเส้นทาง) ภายในรหัสได้หรือไม่? ฉันลอง subprocess.popen และพยายามค้นหาตัวแปร ฉันคิดว่าฉันสามารถใช้ stdin ได้ แต่ไม่ได้ผลจริงๆ ฉันจะขอบคุณมากถ้าคุณสามารถให้ตัวอย่างกับ subprocess.txt กับไฟล์ปฏิบัติการที่อยู่ใน C: \ flow_model ชื่อของไฟล์ปฏิบัติการเป็น flow.exe และชื่อของไฟล์อินพุตที่อยู่ในโฟลเดอร์เดียวกับ sac_bsl.txt
Mesut

ส่วน "ขอชื่อไฟล์อินพุต" เป็นส่วนที่ยุ่งยาก การไม่รู้อะไรเลยเกี่ยวกับวิธีการเข้ารหัส exe ดังที่ฉันได้กล่าวไปแล้วwexpectเป็นวิธีที่ดีที่สุดเนื่องจากช่วยให้คุณสามารถจำลองสิ่งที่ไฟล์ exe จะเห็นเมื่อเรียกใช้ที่หน้าต่าง cmd
Alex Martelli

42

หากใช้ Python 2.7 ขึ้นไป (โดยเฉพาะก่อน Python 3.5) คุณสามารถใช้สิ่งต่อไปนี้:

import subprocess
  • subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False) รันคำสั่งที่อธิบายโดย args รอให้คำสั่งเสร็จสิ้นจากนั้นส่งคืนแอตทริบิวต์ returncode
  • subprocess.check_call(args, *, stdin=None, stdout=None, stderr=None, shell=False) รันคำสั่งพร้อมอาร์กิวเมนต์ รอให้คำสั่งเสร็จสมบูรณ์ ถ้ารหัสส่งคืนเป็นศูนย์จะส่งคืนมิฉะนั้นจะเพิ่มค่าโทรโปรเซส วัตถุ calledProcessError จะมีโค้ดส่งคืนในแอตทริบิวต์ returncode

ตัวอย่าง: subprocess.check_call([r"C:\pathToYourProgram\yourProgram.exe", "your", "arguments", "comma", "separated"])

ในสตริง Python ปกติชุดอักขระ \ U จะส่งสัญญาณการหลีกเลี่ยงจุดรหัส Unicode แบบขยาย

นี่คือลิงค์ไปยังเอกสาร: http://docs.python.org/3.2/library/subprocess.html

สำหรับ Python 3.5+ ตอนนี้คุณสามารถใช้ run () ได้ในหลาย ๆ กรณี: https://docs.python.org/3.5/library/subprocess.html#subprocess.run


7
Python 3.6.3 แนะนำให้รัน ()
Ricardo Zorio

34

วิธีที่ง่ายที่สุดคือ:

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

มันได้ผล; ฉันลองแล้ว


1
ทำงานได้อย่างถูกต้อง แต่มีวิธีเพิ่มพารามิเตอร์เช่น -start และอื่น ๆ หรือไม่?
Bassem Shahin

1
ไม่ทำงาน: module 'os' has no attribute 'startfile'. (ใช้
python3.6

เห็นได้ชัดว่าไม่ได้ทำงานในสิ่งที่เกี่ยวข้องกับ Windows ตรงกันข้ามกับความประทับใจว่าเอกสารให้
not2qubit

ดูเหมือนจะใช้ได้กับ ipython เท่านั้น
user3273814

24

ฉันจะลองใส่ 'r' หน้าเส้นทางของคุณถ้าฉันเป็นคุณเพื่อระบุว่ามันเป็นสตริงดิบ - จากนั้นคุณจะไม่ต้องใช้เครื่องหมายทับ ตัวอย่างเช่น:

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

19

การใช้งานของคุณถูกต้อง ฉันพนันได้เลยว่าโปรแกรมภายนอกของคุณคือ flow.exe จำเป็นต้องดำเนินการในไดเร็กทอรีของมันเนื่องจากมันเข้าถึงไฟล์ภายนอกบางไฟล์ที่เก็บไว้ในนั้น

ดังนั้นคุณอาจลอง:

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

(ระวังเครื่องหมายคำพูดคู่ในเครื่องหมายคำพูดเดี่ยว ... )


ทำงานได้อย่างสมบูรณ์เราจะจัดเก็บผลลัพธ์ลงในดาต้าเฟรมโดยตรงได้อย่างไร
Sade



4

ลอง

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

ลองแล้วสิ่งเดียวกันก็เกิดขึ้น ดูเหมือนว่าจะเปิดหน้าต่าง cmd แต่มันจะไม่เรียกใช้ปฏิบัติการ ฉันลองใช้ไฟล์ปฏิบัติการแยกจากกันและใช้งานได้ดี ฉันยังย้ายโฟลเดอร์เป็น C: / flow_model ไม่ได้สร้างความแตกต่าง ??
เมซุต

2

ถ้าเป็นฉันฉันจะใส่ไฟล์ EXE ในไดเร็กทอรีรูท (C :) และดูว่ามันใช้งานได้หรือไม่ ถ้าเป็นเช่นนั้นอาจเป็นช่องว่าง (ที่กล่าวถึงแล้ว) ในชื่อไดเรกทอรี ถ้าไม่เช่นนั้นอาจเป็นตัวแปรสภาพแวดล้อมบางอย่าง

ลองตรวจสอบคุณ stderr ด้วย (โดยใช้คำตอบก่อนหน้าโดย int3):

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

รหัสอาจไม่ถูกต้องทั้งหมดเนื่องจากฉันมักไม่ใช้ Popen หรือ Windows แต่ควรให้แนวคิด อาจเป็นไปได้ว่าข้อความแสดงข้อผิดพลาดอยู่ในสตรีมข้อผิดพลาด


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

1
โปรดเพิ่มคำอธิบายว่าเหตุใดรหัสของคุณจึงแก้ปัญหานี้ได้
rje

โพสต์นี้โดยพื้นฐานแล้วจะจัดการกับไฟล์ * .exe ที่กำลังดำเนินการเช่นเดียวกับที่คุณใช้ไฟล์ windows * .bat
SamAct

2

ใน python 2.6 ใช้สตริงที่อยู่ภายในเครื่องหมายคำพูด "และเครื่องหมายอะพอสทรอฟี" และเปลี่ยน single / เป็น double // ตัวอย่างการทำงานของคุณจะมีลักษณะดังนี้:

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

นอกจากนี้คุณสามารถใช้พารามิเตอร์ใดก็ได้หากโปรแกรมของคุณนำเข้า

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

ในที่สุดคุณสามารถใช้ตัวแปรสตริงดังตัวอย่างคือการพล็อตโดยใช้ gnuplot โดยตรงจาก 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

นั่นคือการพยายามดำเนินการC:\Documentsกับข้อโต้แย้งของ"and", "Settings/flow_model/flow.exe"?

subprocess.call()นอกจากนี้คุณอาจพิจารณา


0

นั่นเป็นการใช้งานที่ถูกต้อง แต่บางทีช่องว่างในชื่อพา ธ อาจทำให้สับสนได้ด้วยเหตุผลบางประการ

คุณอาจต้องการเรียกใช้โปรแกรมภายใต้ cmd.exe ด้วยเพื่อให้คุณสามารถเห็นผลลัพธ์จาก flow.exe ที่อาจบ่งชี้ข้อผิดพลาด


0

มีโซลูชันที่แตกต่างกันมากมายและผลลัพธ์จะขึ้นอยู่กับ:

  • ระบบปฏิบัติการที่คุณใช้: Windows, Cygwin, Linux, MacOS
  • เวอร์ชัน python ที่คุณใช้: Python2 หรือ Python3x

เนื่องจากฉันได้ค้นพบบางสิ่งที่อ้างว่าใช้งานได้เฉพาะใน Windows เท่านั้นไม่อาจเป็นเพราะฉันบังเอิญใช้ Cygwin ซึ่งเป็นการชิงไหวชิงพริบของระบบปฏิบัติการในการจัดการกับเส้นทางของ Windows สิ่งอื่น ๆ ใช้ได้เฉพาะในระบบปฏิบัติการที่ใช้ pure * nix หรือใน Python2 หรือ 3

นี่คือสิ่งที่ฉันค้นพบ:

  • โดยทั่วไปos.system()เป็นวิธีการที่ให้อภัยมากที่สุด
  • os.startfile()เป็นการให้อภัยน้อยที่สุด (เฉพาะ Windows && ถ้าคุณโชคดี)
  • subprocess.Popen([...]) ไม่แนะนำ
  • subprocess.run(winView, shell=True) วิธีที่แนะนำ!
  • ความทรงจำที่ใช้subprocessสำหรับสิ่งที่อาจก่อให้เกิดความเสี่ยงด้านความปลอดภัย

ลองสิ่งเหล่านี้:

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)

ถาม: ทำไมคุณถึงต้องการใช้explorerใน Windows

ตอบ: เนื่องจากหากคุณต้องการดูผลลัพธ์ของไฟล์ใหม่บางไฟล์ explorer จะเปิดไฟล์โดยอัตโนมัติด้วยโปรแกรม windows เริ่มต้นที่คุณตั้งค่าไว้สำหรับไฟล์ประเภทนั้น จึงไม่จำเป็นต้องระบุโปรแกรมเริ่มต้นใหม่ที่จะใช้


0

สำหรับคำถามข้างต้นวิธีนี้ใช้ได้ผล

เพียงแค่เปลี่ยนเส้นทางไปยังตำแหน่งที่ไฟล์ปฏิบัติการของคุณอยู่

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

ที่นี่ test1.pdf rootimage สำหรับรหัสของฉัน


คุณลืมปิด"ในos.system?
Suraj Rao
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.