Làm cách nào để thực thi chương trình từ Python? os.system bị lỗi do khoảng trắng trong đường dẫn


273

Tôi có một tập lệnh Python cần thực thi một chương trình bên ngoài, nhưng vì một số lý do không thành công.

Nếu tôi có đoạn script sau:

import os;
os.system("C:\\Temp\\a b c\\Notepad.exe");
raw_input();

Sau đó, nó không thành công với lỗi sau:

'C: \ Temp \ a' không được nhận dạng dưới dạng lệnh bên trong hoặc bên ngoài, chương trình có thể hoạt động hoặc tệp bó.

Nếu tôi thoát khỏi chương trình với dấu ngoặc kép:

import os;
os.system('"C:\\Temp\\a b c\\Notepad.exe"');
raw_input();

Sau đó, nó hoạt động. Tuy nhiên, nếu tôi thêm một tham số, nó sẽ ngừng hoạt động trở lại:

import os;
os.system('"C:\\Temp\\a b c\\Notepad.exe" "C:\\test.txt"');
raw_input();

Cách đúng đắn để thực hiện một chương trình và chờ đợi nó hoàn thành là gì? Tôi không cần phải đọc đầu ra từ nó, vì đây là một chương trình trực quan thực hiện công việc và sau đó chỉ thoát, nhưng tôi cần đợi nó hoàn thành.

Cũng lưu ý, di chuyển chương trình đến một đường dẫn không có khoảng cách cũng không phải là một lựa chọn.


Điều này cũng không hoạt động:

import os;
os.system("'C:\\Temp\\a b c\\Notepad.exe'");
raw_input();

Lưu ý các dấu ngoặc đơn / đôi được hoán đổi.

Có hoặc không có tham số cho Notepad ở đây, nó không thành công với thông báo lỗi

Tên tệp, tên thư mục hoặc cú pháp nhãn âm lượng không chính xác.


Sử dụng cái này: os.system(r'C:\temp\"a b c"\Notepad.exe') hoặc cái này:os.system('C:\\temp\\"a b c"\\Notepad.exe')
chanzerre

Đối với khách truy cập trong tương lai, nếu bạn muốn chạy một ứng dụng có đối số (sử dụng quy trình con). bạn cần phân chia các đối số của mình theo khoảng trắng và chuyển từng đối số riêng lẻ. Ví dụ: đây là từ một tập tin bat : "C:\Program Files\GDAL\gdal_translate.exe" -ot byte -of GTIFF -scale -co PHOTOMETRIC=CMYK "cmyk-16.tif" "cmyk-8_out.tif". Trong Python, nó trở thành : ["C:\\Program Files\\GDAL\\gdal_translate.exe", "-ot", "byte", "-scale", "-co", "PHOTOMETRIC=CMYK", "input_cmyk-16.tif", "output_cmyk-8.tif"].
akinuri

Câu trả lời:


297

subprocess.callsẽ tránh được các vấn đề với việc phải đối phó với các quy ước trích dẫn của các loại vỏ khác nhau. Nó chấp nhận một danh sách, thay vì một chuỗi, vì vậy các đối số được phân tách dễ dàng hơn. I E

import subprocess
subprocess.call(['C:\\Temp\\a b c\\Notepad.exe', 'C:\\test.txt'])

81
Việc sử dụng chuỗi thô trong windows sẽ đơn giản hơn nhiều: r "C: \ Temp \ abc \ Notepad.exe"
PierreBdR

1
Có, các hàm os.exec * sẽ thay thế quy trình hiện tại, vì vậy quy trình python của bạn sẽ không tiếp tục. Chúng được sử dụng nhiều hơn trên unix trong đó phương thức chung cho shell để khởi chạy lệnh là fork () và sau đó exec () trong đứa trẻ.
Brian

1
Phương thức windows cho điều này là họ os.spawn, có thể được sử dụng thay thế. quy trình con có tính di động cao hơn và cung cấp sự linh hoạt hơn trong việc kiểm soát quy trình (nắm bắt đầu vào / đầu ra, v.v.), vì vậy được ưu tiên.
Brian

6
@PierreBdr: Có một trường hợp mà rawstrings không hoạt động: nơi bạn cần một dấu gạch chéo. ví dụ: r'c: \ foo \ bar \ '. Trên thực tế, có lẽ tốt hơn để sử dụng dấu gạch chéo về phía trước. Chúng được chấp nhận trong toàn bộ API của windows (mặc dù không phải lúc nào cũng bằng một số lệnh shell (ví dụ: sao chép))
Brian

1
Đối với python> = 3,5 subprocess.callnên được thay thế bởi subprocess.run docs.python.org/3/library/subprocess.html#older-high-level-api
gbonetti

67

Đây là một cách khác nhau để làm điều đó.

Nếu bạn đang sử dụng Windows, các hành động sau đây như bấm đúp vào tệp trong Explorer hoặc đặt tên tệp làm đối số cho lệnh "bắt đầu" của DOS: tệp được mở với bất kỳ ứng dụng nào (nếu có) phần mở rộng của nó được liên kết với .

filepath = 'textfile.txt'
import os
os.startfile(filepath)

Thí dụ:

import os
os.startfile('textfile.txt')

Điều này sẽ mở textfile.txt bằng Notepad nếu Notepad được liên kết với các tệp .txt.


1
Có một chức năng tương đương cho các hệ thống * nix?
Romeno

@Romeno: bạn có thể thử: webbrowser.open("textfile.txt")nó sẽ mở trình soạn thảo văn bản. Xem thêm "tự mình bắt đầu chương trình thứ hai, như thể tôi chỉ cần 'nhấp đúp chuột vào chương trình'."
jfs

Trên thiết lập của tôi, textfile.txt cần được đặt trong dấu ngoặc kép, ví dụ:os.startfile('path\to\textfile.txt')
thdoan

34

Các trích dẫn ngoài cùng được sử dụng bởi chính Python và Windows shell không nhìn thấy nó. Như đã đề cập ở trên, Windows chỉ hiểu dấu ngoặc kép. Python sẽ chuyển đổi dấu gạch chéo sang dấu gạch chéo ngược trên Windows, vì vậy bạn có thể sử dụng

os.system('"C://Temp/a b c/Notepad.exe"')

'Được Python sử dụng, sau đó chuyển "C: //Temp/abc/Notepad.exe" (dưới dạng đường dẫn Windows, không cần dấu gạch chéo kép) cho CMD.EXE


1
Đây có vẻ là điều tốt nhất trong một kịch bản như os.system('curl URL > file')nơi tôi muốn xem làm mới máy đo tiến độ của cURL cho các tệp thực sự lớn.
Zach Young

Nếu chữ cái đầu tiên sau một dấu chéo ngược có ý nghĩa đặc biệt (ví dụ \t, \nvv) thì đó đặc biệt xuyệc ngược phải được tăng gấp đôi. Trở thành một con đường Windows không có gì để làm với nó.
Ethan Furman

1
Lưu ý rằng nếu bạn sử dụng os.system()trên Windows, cửa sổ cmd sẽ mở và vẫn mở cho đến khi bạn đóng quá trình bắt đầu. IMHO tốt hơn để sử dụng os.startfile().
thdoan

1
Đừng quênimport os
Besi

không hoạt động với tôi stackoverflow.com/questions/56241616/ từ
Gulzar

19

Ít nhất là trong Windows 7 và Python 3.1, os.systemtrong Windows muốn dòng lệnh được trích dẫn kép nếu có khoảng trắng trong đường dẫn đến lệnh. Ví dụ:

  TheCommand = '\"\"C:\\Temp\\a b c\\Notepad.exe\"\"'
  os.system(TheCommand)

Một ví dụ trong thế giới thực đã khiến tôi phải sao chép một ổ đĩa trong VirtualBox. Các subprocess.callgiải pháp trên không làm việc vì một số vấn đề quyền truy cập, nhưng khi tôi dụng dấu ngoặc kép lệnh, os.systemtrở thành hạnh phúc:

  TheCommand = '\"\"C:\\Program Files\\Sun\\VirtualBox\\VBoxManage.exe\" ' \
                 + ' clonehd \"' + OrigFile + '\" \"' + NewFile + '\"\"'
  os.system(TheCommand)

Điều đó là vậy đó! Tôi muốn đi subprocess, nhưng đôi khi os.systemos.popen(...).read()chỉ nhanh hơn để gõ. BTW, bạn không cần phải thoát dấu ngoặc kép trong một lần, tức là '""C:\\Temp\\a b c\\Notepad.exe""'sẽ làm được.
Tomasz Gandor

9
import win32api # if active state python is installed or install pywin32 package seperately

try: win32api.WinExec('NOTEPAD.exe') # Works seamlessly
except: pass

và dường như không cần trích dẫn với phương thức này, ví dụ win32api.WinExec ('pythonw.exe d: \ web2py \ web2py.py -K welcome') khởi động trình lập lịch web2py trong nền.
Tim Richardson

@rahul và có ngoại trừ đối số cho thực thi không? Vì vậy, nếu bạn muốn Notepad để mở một tập tin hoặc đó là riêng biệt?
sayth


3

Tôi nghi ngờ đó là vấn đề tương tự như khi bạn sử dụng phím tắt trong Windows ... Hãy thử điều này:

import os;
os.system("\"C:\\Temp\\a b c\\Notepad.exe\" C:\\test.txt");

xin lỗi, điều đó cũng không hoạt động, câu hỏi được chỉnh sửa để phản ánh điều này.
Lasse V. Karlsen

Tôi nghĩ các cửa sổ chỉ sử dụng ", thay vì 'để trích dẫn. Điều này có thể sẽ hoạt động nếu bạn thay đổi điều này. Tuy nhiên, bạn vẫn sẽ gặp vấn đề với nếu bạn đã nhúng trích dẫn, v.v.
Brian

Tôi nghĩ rằng nó đã mất cả hai, nhưng bạn có thể đúng. Tôi biết nó hoạt động (trong vỏ ít nhất) với dấu ngoặc kép.
Matthew Scharley

+1 đây là phiên bản tốt nhất, Windows XP, phiên bản gia đình 2007 hoạt động tốt

0

Giả sử chúng tôi muốn chạy máy chủ web Django của bạn (trong Linux) rằng có khoảng trống giữa đường dẫn của bạn (path = '/home/<you>/<first-path-section> <second-path-section>'), vì vậy hãy làm như sau:

import subprocess

args = ['{}/manage.py'.format('/home/<you>/<first-path-section> <second-path-section>'), 'runserver']
res = subprocess.Popen(args, stdout=subprocess.PIPE)
output, error_ = res.communicate()

if not error_:
    print(output)
else:
    print(error_)

[ Lưu ý ]:

  • Đừng quên quyền truy cập: chmod 755 -R <'yor path'>
  • manage.py là tuyệt vời: chmod +x manage.py

0

Đối với Python 3.7, hãy sử dụng sub process.call . Sử dụng chuỗi thô để đơn giản hóa các đường dẫn Windows:

import subprocess
subprocess.call([r'C:\Temp\Example\Notepad.exe', 'C:\test.txt'])

0

Không cần quá trình phụ, Nó có thể được thực hiện đơn giản bằng cách

GitPath = "C: \ Chương trình tập tin \ Git \ git-bash.exe" # Đường dẫn tệp ứng dụng trong tài liệu của tôi GITBASH os.startfile (GitPath)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.