[python] 🚀 Python'da harici bir komut çağırmak
Bir Python betiğinden harici bir komutu (Unix kabuğuna veya Windows komut istemine yazmışım gibi) nasıl çağırırsınız?
Standart kütüphanedeki alt işlem modülüne bakın :
Avantajı subprocess vs. system onu (alabilirsiniz daha esnek olmasıdır stdout , stderr "gerçek" durum kodu, daha iyi hata işleme, vs ...).
Resmi belgeler önerir subprocess alternatif üzerinde modülü os.system() :
subprocess Modül yeni süreçler yumurtlama ve onların sonuçlarını almak için, daha güçlü olanaklar sağlar; Bu modülü kullanmak bu işlevi kullanmak için tercih edilir [ os.system() ].
Altişlem Modülü ile değiştirilmesi Yaşlı Fonksiyonlar bölümünde subprocess belgelerinde bazı yararlı tarifi olabilir.
3.5'ten önceki Python sürümleri için call şunları kullanın :
David Cournapeau2008-09-182008-09-18 01:39:35Z
İşte harici programları çağırmanın yollarını ve her birinin avantaj ve dezavantajlarını özetleyen:
os.system("some_command with args") komutu ve argümanları sisteminizin kabuğuna iletir. Bu çok hoş, çünkü aslında bir kerede birden fazla komut çalıştırabilir, boru ve giriş / çıkış yönlendirmesini ayarlayabilirsiniz. Örneğin:
Bununla birlikte, bu elverişli olsa da, boşluklar vb. Gibi kabuk karakterlerinden kaçışınızı manuel olarak ele almanız gerekir. Öte yandan, bu aynı zamanda sadece harici komutlar yerine sadece kabuk komutları olan komutları çalıştırmanıza izin verir. Belgelere bakınız .
stream = os.popen("some_command with args") os.system Bu işlem için standart giriş / çıkışa erişmek için kullanabileceğiniz dosya benzeri bir nesne vermesi dışında aynı şeyi yapacağız . Hepsi G / Ç'yi biraz farklı şekilde ele alan 3 popen varyantı daha vardır. Her şeyi bir dize olarak iletirseniz, komutunuz kabuğa iletilir; eğer onları bir liste halinde geçirirseniz, hiçbir şeyden kaçmak için endişelenmenize gerek kalmaz. Belgelere bakınız .
Popen Sınıf subprocess modülü. Bunun yerine geçmesi amaçlanmıştır os.popen ancak bu kadar kapsamlı olmaları nedeniyle biraz daha karmaşık olmalarının dezavantajı vardır. Örneğin, şöyle diyeceksiniz:
ancak, tüm seçeneklerin 4 farklı popen işlevi yerine bir birleştirilmiş sınıfta olması güzel. Belgelere bakınız .
call İşlev subprocess modülü. Bu temelde Popen sınıf gibidir ve aynı argümanların hepsini alır, ancak komut tamamlanana ve size dönüş kodunu verene kadar bekler. Örneğin:
Belgelere bakınız .
Python 3.5 veya daha yenisindeyseniz subprocess.run , yukarıdaki gibi olan ancak daha esnek olan yeni işlevi kullanabilirsiniz CompletedProcess , komut çalıştırmayı tamamladığında bir nesneyi döndürür .
Os modülü aynı zamanda bir C programında sahip olabileceğiniz tüm çatal / exec / spawn işlevlerine de sahiptir, ancak bunları doğrudan kullanmanızı önermiyorum.
subprocess Modül muhtemelen Kullandığınız olmalıdır.
Son olarak, kabuğun bir dizge olarak çalıştırılacağı son komutu geçtiğiniz tüm yöntemlerde ve onu kaçmaktan sorumlu olduğunuzu lütfen unutmayın. İlettiğiniz dizenin herhangi bir kısmına tam olarak güvenilemediği takdirde ciddi güvenlik etkileri vardır . Örneğin, bir kullanıcı dizenin bir kısmını / herhangi bir kısmını giriyorsa. Emin değilseniz, bu metodları sadece sabitler ile kullanın. Size bir ipucu vermek için bu kodu göz önünde bulundurun:
ve kullanıcının tüm dosya sistemini silebilecek "annem beni sevmedi & & rm -rf /" bir şey girdiğini hayal edin.
Eli Courtwright2008-09-182008-09-18 13:11:46Z
Borudaki stdout verilerle istediğiniz şeyi yapmakta özgürsünüz . Aslında, sadece bu parametreleri ( stdout= ve stderr= ) ihmal edebilirsiniz ve böyle davranır os.system() .
Buradaki fikir, longtask.py işlemi tamamlanana kadar 'subprocess çağrısı' satırında beklemek istemeyeceğinizdir. Ancak örnekten 'burada biraz daha kod' satırından sonra ne olduğu açık değildir.
Hedef platformum freebsd idi, ancak geliştirme pencerelerde yapıldı, bu yüzden ilk önce pencerelerde sorunla karşılaştım.
Çözüm, DETACHED_PROCESS İşlem Oluşturma Bayrağını win API'sındaki temel CreateProcess işlevine iletmektir. Pywin32'yi kurduysanız, bayrağı win32process modülünden içe aktarabilirsiniz, aksi halde kendiniz tanımlamanız gerekir:
/ * UPD 2015.10.27 @eryksun, aşağıdaki açıklamada, anlamsal olarak doğru bayrağın CREATE_NEW_CONSOLE (0x00000010) * / olduğunu not eder.
Freebsd'de başka bir sorunumuz var: ebeveyn işlemi bittiğinde, çocuk işlemlerini de bitirir. Ve bu da CGI-script'de istediğin şey değil. Bazı deneyler, sorunun sys.stdout paylaşımında göründüğünü göstermiştir. Ve çalışma çözümü şuydu:
Kodu diğer platformlarda kontrol etmedim ve freebsd'deki davranışın nedenlerini bilmiyorum. Eğer biri biliyorsa, lütfen fikirlerinizi paylaşın. Python'da arkaplan işlemlerinin başlatılması üzerine googling henüz bir ışık tutmuyor.
Os.system yerine subprocess modülünü kullanmanızı öneririm, çünkü sizin için kaçmayı engeller ve bu nedenle çok daha güvenlidir: http://docs.python.org/library/subprocess.html
Komutun sonuçlarını döndürmek istiyorsanız, kullanabilirsiniz os.popen . Bununla birlikte, bu, 2.6'dan bu yana, diğer cevapların iyi ele aldığı alt süreç modülünün lehine kaldırılmıştır .
Alexandra Franks2008-09-182008-09-18 01:37:49Z
Komutun temizlenmediğinden tehlikeli olduğunu unutmayın. 'Os' ve 'sys' modülleriyle ilgili dokümantasyon için Google'ı size bırakıyorum. Benzer şeyler yapacak birçok işlev (exec * ve spawn *) vardır.
Python ile harici komutları çağırmanıza izin veren birçok kitaplık vardır. Her kütüphane için bir tanım verdim ve harici bir komut çağırmanın bir örneğini gösterdim. Örnek olarak kullandığım komut şudur ls -l (tüm dosyaları listele). Eğer listelediğim kütüphanelerden herhangi biri hakkında daha fazla bilgi edinmek istiyorsanız, her birinin belgelerini bağladım.
Bunların hepsi kütüphaneler:
Umarım bu, hangi kütüphaneyi kullanacağınıza karar vermenize yardımcı olacaktır :)
Alt işlem, harici komutları çağırmanıza ve bunları giriş / çıkış / hata borularına (stdin, stdout ve stderr) bağlamanıza izin verir. Alt işlem çalışan komutlar için varsayılan seçimdir, ancak bazen diğer modüller daha iyidir.
os "işletim sistemine bağlı işlevsellik" için kullanılır. Aynı zamanda harici komutları çağırmak için kullanılabilir os.system ve os.popen (Not: Orada da bir subprocess.popen). os her zaman kabuğu çalıştıracak ve ihtiyacı olmayan veya nasıl kullanılacağını bilmeyen insanlar için basit bir alternatiftir subprocess.run .
plumbum, "script benzeri" Python programları için bir kütüphanedir. İşlevler gibi programları olduğu gibi çağırabilirsiniz sh . Plumbum kabuksuz bir boru hattı çalıştırmak istiyorsanız kullanışlıdır.
pexpect, alt uygulamaları üretmenize, kontrol etmenize ve çıktılarında kalıpları bulmanıza olanak sağlar. Bu, Unix'te bir tty bekleyen komutlar için alt işlemlere daha iyi bir alternatiftir.
kumaş Python 2.5 ve 2.7 kütüphanesidir. Yerel ve uzak kabuk komutlarını çalıştırmanıza izin verir. Kumaş, komutları güvenli bir kabukta (SSH) çalıştırmak için basit bir alternatiftir
elçi "insanlar için alt süreç" olarak bilinir. subprocess Modülün çevresinde uygun bir ambalaj olarak kullanılır .
commands için sarma işlevlerini içerir os.popen , ancak subprocess daha iyi bir alternatif olduğundan Python 3'ten kaldırılmıştır .
Düzenleme, JF Sebastian'ın yorumuna dayanıyordu.
Tom Fuller2016-10-292016-10-29 14:02:50Z
Her zaman fabric böyle şeyler için kullanırım :
Bir örneğe bak:
Jorge E. Cardona2012-03-132012-03-13 00:12:54Z
Harici programların / komutların, hatta ssh, ftp, telnet'in, vb. Etkileşimli olarak kontrol edilmesine olanak tanır.
Aradığınız komutun çıktısına ihtiyacınız varsa, subprocess.check_output (Python 2.7+) komutunu kullanabilirsiniz .
Ayrıca kabuk parametresini not edin .
Kabuk ise True , belirtilen komut kabuktan çalıştırılır. Python'u, çoğu sistem kabuğunda sunduğu gelişmiş kontrol akışı için kullanıyorsanız ve yine de kabuk boruları, dosya adı joker karakterleri, ortam değişken genişlemesi ve ~ bir kullanıcının evine genişletme gibi diğer kabuk özelliklerine kolay erişim sağlamak istiyorsanız, bu yararlı olabilir. dizin. Ancak, not Python kendisinin uygulamalarını sunduğu birçok kabuk gibi özellikleri (özellikle glob , fnmatch , os.walk() , os.path.expandvars() , os.path.expanduser() , ve shutil ).
Facundo Casco2011-04-282011-04-28 20:29:29Z
Alt işlem modülünü kullan (Python 3):
Önerilen standart yoldur. Bununla birlikte, daha karmaşık görevler (borular, çıktılar, girdiler vb.) Oluşturmak ve yazmak için can sıkıcı olabilir.
ProTip: shlex.split için komutu ayrıştırmak için yardımcı olabilir run , call ve diğer subprocess durumda fonksiyonları istemediğiniz (ya yapamazsın!) Listeleri şeklinde bunları sağlamak:
Dış bağımlılıkları önemsemiyorsanız , plumbum kullanın :
En iyi subprocess sarmalayıcıdır. Çapraz platformdur, yani hem Windows hem de Unix benzeri sistemlerde çalışır. Tarafından yükleyin pip install plumbum .
Başka bir popüler kütüphane sh :
Ancak, sh Windows desteği düştü, bu yüzden eskisi gibi mükemmel değil. Tarafından yükleyin pip install sh .
Ben buyruklarımı böyle çalıştırıyorum. Bu kod hemen hemen ihtiyacınız olan her şeye sahiptir
Usman Khan2012-10-282012-10-28 05:14:01Z
subprocess.run Kodunuzun önceki Python sürümleriyle uyumluluğunu sürdürmesi gerekmiyorsa , Python 3.5'ten itibaren önerilen yaklaşım budur . Daha tutarlı ve Elçi ile benzer kullanım kolaylığı sunuyor. (Borular olsa da kolay değil. Nasıl yapılacağı için bu soruya bakın .)
İşte dokümanlardan bazı örnekler .
Başarısız olan koşuda yükseltme:
Envoy'u denemeyi tavsiye ederim . Alt süreçler için bir sarmalayıcıdır ve sırayla eski modülleri ve fonksiyonları değiştirmeyi amaçlar . Elçi insanlar için alt süreçtir.
Beniokudan örnek kullanım :
Sonuç çıktısı ile:
... ya da çok basit bir komut için:
Ben Hoffstein2008-09-182008-09-18 01:43:30Z
Orada da Plumbum
os.system Tamam, ama biraz tarihli. Aynı zamanda çok güvenli değil. Bunun yerine, deneyin subprocess . subprocess doğrudan sh demez ve bundan daha güvenlidir os.system .
Daha fazla bilgi alın burada .
Martin W2008-09-182008-09-18 01:53:27Z
subprocess.run Bir CompletedProcess nesneyi döndüren basit, kullanım :
Python 3.5'ten itibaren , belgeler subprocess.run'u önerir :
Alt işlemlerin başlatılması için önerilen yaklaşım, kullanabileceği tüm kullanım durumlarında run () işlevini kullanmaktır. Daha gelişmiş kullanım durumları için, temel Popen arayüzü doğrudan kullanılabilir.
İşte mümkün olan en basit kullanımın bir örneği - ve aynen istendiği gibi:
run komutun başarıyla tamamlanmasını bekler, sonra bir CompletedProcess nesneyi döndürür . Bunun yerine yükseltir TimeoutExpired (eğer timeout= tartışırsanız) veya CalledProcessError (başarısız olursa ve geçerseniz check=True ).
Çıktıyı yakalamak istiyorsanız subprocess.PIPE , uygun olana geçebilirsiniz stderr veya stdout :
(Sürüm bilgisinin stdout yerine stderr'e konması ilginç ve biraz sezgisel buluyorum.)
Bir programlı olarak oluşturulmuş bir dize sağlamaya kolayca bir komut dizesi sağlamaktan (soru sorduğu gibi) kolaylıkla geçebilir. Dizeleri programlı olarak oluşturma. Bu potansiyel bir güvenlik sorunudur. Girdiye güvenmediğinizi varsaymak daha iyidir.
Not, sadece args konumsal olarak geçirilmelidir.
İşte kaynaktaki asıl imza ve aşağıda gösterildiği gibi help(run) :
popenargs Ve kwargs verilen Popen yapıcı. alt işlemin stdinine aktarılacak input olan bir bayt dizisi (veya kodlamayı belirtirseniz unicode veya universal_newlines=True ) olabilir.
Belgeler açıkladı timeout= ve check=True benden daha iyi:
Zaman aşımı argümanı Popen.communicate () öğesine iletilir. Zaman aşımı süresi dolduğunda, çocuk süreci öldürülecek ve beklenecek. Alt işlem sona erdikten sonra TimeoutExpired özel durumu yeniden oluşturulacak.
Eğer kontrol doğruysa ve süreç sıfır olmayan bir çıkış koduyla çıkarsa, CalledProcessError istisnası ortaya çıkar. Bu istisnanın özellikleri argümanları, çıkış kodunu ve eğer yakalanırsa stdout ve stderr'yi tutar.
ve bu örnek check=True , bulabileceğimden daha iyi:
Bunun sadece ark listesinin konumsal olarak iletilmesi gerektiğini gösterdiğini unutmayın. Kalan argümanları anahtar sözcük argümanları olarak iletin
Yerine ne zaman kullanılır Popen ? Sadece tartışmalara dayanarak kullanım örneği bulmakta zorlanırdım. Popen Bununla birlikte, doğrudan kullanımı poll , 'send_signal', 'sonlandır' ve 'bekle' gibi yöntemlerine erişmenizi sağlar .
İşte kaynakta Popen verilen imza . Bunun, bilginin en kesin kapsüllenmesi olduğunu düşünüyorum (aksine ):https://github.com/python/cpython/blob/master/Lib/subprocess.py%23L587#L587 help(Popen)
Ama daha bilgilendirici belgeler : Popen
Yeni bir süreçte bir çocuk programı yürütün. POSIX'de sınıf, alt programı yürütmek için os.execvp () benzeri bir davranış kullanır. Windows'ta, sınıf Windows CreateProcess () işlevini kullanır. Popen argümanları aşağıdaki gibidir.
Kalan belgelerin anlaşılması Popen okuyucu için bir alıştırma olarak bırakılacaktır.
Aaron Hall2017-10-182017-10-18 16:37:52Z
Daha fazla os fonksiyon için, işte belgeler.
Samadi Salahedine2018-04-302018-04-30 13:47:17Z
os modülünü kullan
abhi krishnan2018-07-272018-07-27 08:10:20Z
subprocess.Popen <command> 'ı bir alt işlem olarak yürütür. Benim durumumda, <b> başka bir programla iletişim kurması gereken <a> dosyasını çalıştırmam gerekiyor, <b>.
Alt işlemi denedim ve yürütme başarılı oldu. Ancak <b> <a> ile iletişim kuramadı. Her ikisini de terminalden çalıştırdığımda her şey normal.
Eğer denerseniz os.system("kwrite") , program akış donar kullanıcı kapanır KWRITE kadar. Bunun üstesinden gelmek için bunun yerine denedim os.system(konsole -e kwrite) . Bu sefer program akmaya devam etti, ancak kwrite konsolun alt işlemi oldu.
Herkes kwrite'ı alt işlem olarak çalıştırmaz (örn. Sistem monitöründe ağacın en sol kenarında görünmesi gerekir).
Atinc Delican2010-01-082010-01-08 21:11:30Z
subprocess.check_call dönüş değerlerini test etmek istemiyorsanız kullanışlıdır. Herhangi bir hataya istisna atar.
Sublex ile birlikte alt işlemi kullanma eğilimindeyim (alıntılanan dizgelerin kaçışını ele almak için):https://docs.python.org/2/library/shlex.html
Emil Stenström2014-04-302014-04-30 14:37:04Z
Sadeliği için shell_command'ı oldukça seviyorum . Alt işlem modülünün üstüne inşa edilmiştir.
os.system sonuçları saklamanıza izin vermez, bu nedenle sonuçları bir listede saklamak veya başka bir şey yapmak istiyorsanız subprocess.call .
Saurabh Bangad2012-06-112012-06-11 22:28:35Z
Temelde şu an için popen ve shlex için bir sarıcı. Ayrıca, boru komutlarını da destekler, böylece Python'da komutları daha kolay zincirleyebilirsiniz. Böylece şöyle şeyler yapabilirsiniz:
Linux altında, bağımsız olarak çalışacak harici bir komut çağırmak istemeniz durumunda (python betiği sona erdikten sonra çalışmaya devam eder), görev biriktiricisi veya at komutu olarak basit bir sıra kullanabilirsiniz.
Görev biriktiricisine bir örnek:
Görev biriktiricisi ( ts ) hakkında notlar :
Yüklemek ts yönetici ayrıcalıkları gerektirmez. Kaynaktan basit bir şekilde indirebilir ve derleyebilir make , yolunuza ekleyebilir ve işiniz biter.
Yuval Atzmon2016-11-272016-11-27 00:15:34Z
Popen'i kullanabilir ve sonra prosedürün durumunu kontrol edebilirsiniz:
Alt süreci kontrol edin .
Javadoc'ta harici bir URL'ye mi bağlanılıyor?
Python'da “SyntaxError:“ Yazdırmak ”çağrısı sırasında parantezin eksik olması ne anlama geliyor?
Python'da Bash komutlarını çalıştırma
PowerShell'deki çıktıyı harici bir işlemden bir değişkene nasıl yakalarım?
Python'da boş bir dize bölündüğünde, split ('\ n') [''] döndürürken split () neden boş bir liste döndürüyor?
Angular2’de harici bir URL’ye nasıl yönlendirilir?
Python tercüman kabuğunda son komut nasıl tekrarlanır?
Harici bir komutu Python'dan eşzamansız olarak nasıl çalıştırabilirim?
PHP komut isteminde bir iç veya dış komut olarak tanınmıyor
Python'da çağıran fonksiyonun modülünün __name__ ismini alın
Git mergetool istenmeyen .orig dosyaları oluşturur
IPv4 için izin verilen en büyük TCP / IP ağ bağlantı noktası numarası nedir?
CocoaPods kullanıyorsanız .gitignore'a ne gider?
Maven 3 build.plugins.plugin.version hakkında uyarılar
HTML dosyalarını yalnızca kaynaklarını görüntülemek yerine doğrudan GitHub'dan çalıştırabilir miyim?
İfadede bir kabuğunda birden fazla koşul nasıl temsil edilir?
Mobil düzende Bootstrap 3 sütun sırasını nasıl değiştiririm?
CHECKED istisnalarını Java 8 akışlarının içinden nasıl fırlatabilirim?