Buradaki diğer cevaplar, subprocess
belgelerde de belirtilen güvenlik uyarılarını yeterince açıklamaktadır . Ancak buna ek olarak, çalıştırmak istediğiniz programı başlatmak için bir kabuk başlatmanın yükü, kabuğun işlevselliğini gerçekten kullanmadığınız durumlar için genellikle gereksizdir ve kesinlikle saçmadır. Ayrıca, ek gizli karmaşıklık sizi korkutmalıdır, özellikle kabuk veya sağladığı hizmetlere aşina .
Kabuk ile etkileşimlerin önemsiz olduğu durumlarda, artık Python betiğinin (gelecekteki kendiniz olabilir veya olmayabilir) okuyucu ve bakıcısının hem Python hem de kabuk betiğini anlaması gerekir. Python'un "açık, örtük olmaktan daha iyidir" sloganını hatırlayın ;Python kodu, eşdeğer (ve genellikle çok kısa) kabuk komut dosyasından biraz daha karmaşık olsa bile, kabuğu kaldırmak ve işlevselliği yerel Python yapılarıyla değiştirmek daha iyi olabilir. Harici bir süreçte yapılan işi en aza indirmek ve kontrolü kendi kodunuz dahilinde olabildiğince uzak tutmak genellikle iyi bir fikirdir, çünkü sadece görünürlüğü geliştirir ve istenen veya istenmeyen yan etki risklerini azaltır.
Joker karakter genişletmesi, değişken enterpolasyon ve yeniden yönlendirme, yerel Python yapılarıyla kolayca değiştirilebilir. Parçaların veya hepsinin Python'da makul bir şekilde yeniden yazılamadığı karmaşık bir kabuk boru hattı, belki de kabuğu kullanmayı düşünebileceğiniz tek durum olacaktır. Yine de performans ve güvenlik sonuçlarını anladığınızdan emin olmalısınız.
Önemsiz durumda, önlemek için shell=True
, sadece değiştirin
subprocess.Popen("command -with -options 'like this' and\\ an\\ argument", shell=True)
ile
subprocess.Popen(['command', '-with','-options', 'like this', 'and an argument'])
İlk argümanın execvp()
nasıl iletileceği dizelerin bir listesi olduğuna ve dizelerden ve ters eğik çizgiden kaçan kabuk metakarakterlerinin genellikle nasıl gerekli olmadığına (veya yararlı veya doğru) dikkat edin. Belki de bkz. Tırnaklar ne zaman bir kabuk değişkeni etrafına sarılır?
Bir yana, paketteki Popen
daha basit sarmalayıcılardan birinin istediğiniz şeyi yapmasından kaçınmak subprocess
istersiniz. Yeterince yeni bir Python'unuz varsa, muhtemelen kullanmalısınız subprocess.run
.
- Çalıştırdığınız
check=True
komut başarısız olursa başarısız olur.
- Bununla
stdout=subprocess.PIPE
birlikte komutun çıktısını yakalar.
- Biraz belirsiz,
universal_newlines=True
çıktıyı uygun bir Unicode dizgisine deşifre eder (sadece bytes
sistem kodlamasını başka türlü Python 3'te).
Değilse, birçok görev için istediğiniz check_output
başarılı check_call
olup olmadığını kontrol ederken veya toplanacak çıktı yoksa, bir komuttan çıktı almak .
David Korn'dan bir alıntıyla kapatacağım: "Taşınabilir bir kabuk yazmak, taşınabilir bir kabuk komut dosyasından daha kolaydır." subprocess.run('echo "$HOME"', shell=True)
Windows için bile taşınabilir değildir.
-l
iletilir . Dize bağımsız değişkeni , bir liste yerine çoğu durumda ile birlikte kullanılmalıdır ./bin/sh
ls
shell=True
shell=True