Python'dan bir programı nasıl yürütebilirim? os.system yoldaki boşluklar nedeniyle başarısız oluyor


273

Harici bir program yürütmesi gereken bir Python betiği var, ancak bazı nedenlerden dolayı başarısız.

Aşağıdaki komut dosyası varsa:

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

Sonra aşağıdaki hatayla başarısız olur:

'C: \ Temp \ a' dahili veya harici bir komut, çalıştırılabilir program veya toplu iş dosyası olarak tanınmıyor.

Programdan alıntılarla kaçarsam:

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

Sonra işe yarıyor. Ancak, bir parametre eklerseniz, tekrar çalışmayı durdurur:

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

Bir programı yürütmenin ve tamamlanmasını beklemenin doğru yolu nedir? Bir iş yapan ve daha sonra sadece çıkış yapan görsel bir program olduğundan, çıktıyı okumama gerek yok, ancak tamamlanmasını beklemem gerekiyor.

Ayrıca, programı aralıksız bir yola taşımanın da bir seçenek olmadığını unutmayın.


Bu da çalışmaz:

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

Değiştirilen tek / çift tırnaklara dikkat edin.

Not Defteri'ne bir parametre olsun veya olmasın, hata mesajı ile başarısız olur

Dosya adı, dizin adı veya birim etiketi sözdizimi yanlış.


Bunu kullanın: os.system(r'C:\temp\"a b c"\Notepad.exe') veya şunu:os.system('C:\\temp\\"a b c"\\Notepad.exe')
chanzerre

Gelecekteki ziyaretçiler için, bağımsız değişkenli bir uygulama çalıştırmak istiyorsanız (alt işlem kullanarak). argümanlarınızı uzaya ayırmanız ve her birini ayrı ayrı iletmeniz gerekir. Örneğin, bu bir yarasa dosyasından geçerli: "C:\Program Files\GDAL\gdal_translate.exe" -ot byte -of GTIFF -scale -co PHOTOMETRIC=CMYK "cmyk-16.tif" "cmyk-8_out.tif". Python, bu olur: ["C:\\Program Files\\GDAL\\gdal_translate.exe", "-ot", "byte", "-scale", "-co", "PHOTOMETRIC=CMYK", "input_cmyk-16.tif", "output_cmyk-8.tif"].
akinuri

Yanıtlar:


297

subprocess.callçeşitli mermilerin alıntı sözleriyle uğraşmak zorunda kalmadan sorunları önleyecektir. Bir dize yerine bir liste kabul eder, bu nedenle argümanlar daha kolay sınırlandırılır. yani

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

81
Windows'da ham dize kullanmak çok daha basittir: r "C: \ Temp \ abc \ Notepad.exe"
PierreBdR

1
Evet, os.exec * işlevleri geçerli işlemin yerini alır, bu nedenle python işleminiz devam etmez. Bir kabuğun bir komutu başlatması için genel yöntemin çocukta fork () ve ardından exec () olduğu unix'de daha çok kullanılırlar.
Brian

1
Bunun için windows yöntemi, onun yerine kullanılabilecek os.spawn ailesidir. ancak alt süreç daha portatiftir ve sürecin kontrolünde daha fazla esneklik sağlar (girdi / çıktı yakalama vb.), bu yüzden tercih edilir.
Brian

6
@PierreBdr: Rawstring'lerin çalışmadığı bir durum var: sondaki eğik çizgiye ihtiyacınız var. örneğin r'c: \ foo \ bar \ '. Aslında, bunun yerine eğik çizgi kullanmak daha iyidir. Bunlar Windows API'sı boyunca kabul edilir (her zaman bazı kabuk komutları tarafından olmasa da (örneğin kopya))
Brian

1
Python için> = 3.5 subprocess.callyerine subprocess.run docs.python.org/3/library/subprocess.html#older-high-level-api
gbonetti

67

İşte bunu yapmanın farklı bir yolu.

Windows kullanıyorsanız aşağıdakiler Explorer'da dosyayı çift tıklamak veya dosya adını DOS "start" komutuna argüman olarak vermek gibi davranır: dosya, uzantısıyla ilişkilendirilmiş herhangi bir uygulama (varsa) ile açılır .

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

Misal:

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

Not Defteri .txt dosyalarıyla ilişkilendirilirse, textfile.txt dosyasını Not Defteri ile açar.


1
* Nix sistemleri için eşdeğer bir işlev var mı?
2012'de Romeno

@Romeno: deneyebilirsiniz: webbrowser.open("textfile.txt")bir metin editörü açmalıdır . Ayrıca bkz. “İkinci programı tamamen kendi başına başlat, sanki 'üzerine çift tıkladım” gibi.
jfs

Benim kurulumda textfile.txt tırnak içinde olmalı, örneğin:os.startfile('path\to\textfile.txt')
thdoan

34

En dıştaki alıntılar Python'un kendisi tarafından tüketilir ve Windows kabuğu bunu görmez. Yukarıda belirtildiği gibi, Windows yalnızca çift tırnak işaretlerini anlar. Python, eğik çizgileri Windows'ta ters eğik çizgilere dönüştürür, böylece kullanabilirsiniz

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

'Python tarafından tüketilir ve daha sonra "C: //Temp/abc/Notepad.exe" (Windows yolu olarak, çift ters eğik çizgi gerekmez)


1
Bu os.system('curl URL > file'), gerçekten büyük dosyalar için cURL'nin ilerleme ölçer yenilemesini görmek istediğim gibi bir senaryoda en iyisi gibi görünüyor .
Zach Young

Ters eğik çizgiden sonraki ilk harfin özel bir anlamı varsa (yani , vb.) \t, Söz \nkonusu ters eğik çizginin iki katına çıkarılması gerekir. Windows yolu olmanın bununla hiçbir ilgisi yoktur.
Ethan Furman

1
os.system()Windows'da kullanırsanız , cmd penceresinin başlatılan işlemi kapatana kadar açılacağını ve açık kalacağını unutmayın. IMHO kullanmak daha iyi os.startfile().
thdoan

1
Unutmaimport os
Besi


19

En azından Windows 7 ve Python 3.1'de, os.systemkomut yolunda boşluklar varsa , Windows'ta komut satırı çift ​​tırnak içine alınmasını ister . Örneğin:

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

Beni çarptıran gerçek dünya örneği VirtualBox'ta bir sürücüyü klonlamaktı. Yukarıdaki subprocess.callçözüm bazı erişim hakları sorunu nedeniyle işe yaramadı, ancak komutu iki kez alıntıladığımda,os.system mutlu oldu:

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

Hepsi bu kadar! Ben gitmek istiyorum subprocess, ama bazen os.systemve os.popen(...).read()sadece yazmak için daha hızlı. BTW, tek içinde çift tırnak kaçmak gerekmez, yani '""C:\\Temp\\a b c\\Notepad.exe""'yapacak.
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

ve bu yöntemle alıntı yapmaya gerek yok gibi görünüyor, örneğin win32api.WinExec ('pythonw.exe d: \ web2py \ web2py.py -K karşılama') arka planda web2py zamanlayıcısını başlatır.
Tim Richardson

@rahul ve yürütülebilir için argümanlar dışında mı? Not Defteri'nin bir dosyayı açmasını istiyorsanız veya bu ayrı mı?
03:


3

Windows'da kısayolları kullandığınızda aynı sorun olduğundan şüpheleniyorum ... Bunu deneyin:

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

üzgünüm, bu da işe yaramıyor, bunu yansıtmak için düzenlenmiş soru.
Lasse V. Karlsen

Ben pencereler tırnak için sadece 'kullanır' düşünüyorum. Bu muhtemelen bunu değiştirirseniz işe yarayacak. Ancak tırnak vb gömülü varsa yine de sorun olacak
Brian

İkisini de aldığını düşündüm, ama muhtemelen haklısın. Çift tırnak ile (en az kabukta) çalıştığını biliyorum.
Matthew Scharley

+1 bu en iyisi, windows XP, 2007 ev baskısı güzel çalıştı

0

Django web sunucunuzu (Linux'ta) yolunuz arasında boşluk (path = '/home/<you>/<first-path-section> <second-path-section>') olduğunu çalıştırmak istediğimizi varsayalım, şunları yapın :

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_)

[ Not ]:

  • İzne erişmeyi unutmayın: chmod 755 -R <'yor path'>
  • manage.py aşılabilir: chmod +x manage.py

0

Python 3.7 için subprocess.call dosyasını kullanın . Windows yollarını basitleştirmek için ham dize kullanın:

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

0

Alt sürece gerek yok, sadece tarafından elde edilebilir

GitPath = "C: \ Program Files \ Git \ git-bash.exe" # Mycase'deki Uygulama Dosyası Yolu, GITBASH os.startfile (GitPath)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.