56 Soru: Python'da harici bir komut çağırmak

tarafından oluşturulan soru Wed, Apr 24, 2019 12:00 AM

Harici bir komutu (Unix kabuğuna veya Windows komut istemine yazmışım gibi) Python komut dosyasından nasıl arayabilirim?

    
4297
30 Yanıtlar                              30                         

Standart kütüphanedeki alt işlem modülüne bakın:

 
import subprocess
subprocess.run(["ls", "-l"])

alt işlemin ve sistemin avantajı, daha esnek olmasıdır (stdout, stderr, "gerçek" durum kodunu, daha iyi hata işlemlerini alabilirsiniz, vs ...).

resmi belgeler , alt işlem üçlü > alternatif os.system () üzerinden modül:

  

Alt işlem modülü, yeni süreçler oluşturmak ve 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() ].

" Eski İşlevlerin Değiştirilmesiyle" alt işlem dokümantasyonundaki alt işlem Modülü "bölümünde bazı yararlı tarifler bulunabilir.

Python'un eski sürümleri çağrı çağrısı:

 
import subprocess
subprocess.call(["ls", "-l"])
    
4140
2019-04-01 22: 39: 54Z
  1. Değişken ikamesini kullanmanın bir yolu var mı? IE echo $PATH kullanarak call(["echo", "$PATH"]) yapmaya çalıştım, ancak herhangi bir değişiklik yapmak yerine $PATH numaralı değişmez dizeyi tekrarladı. PATH ortam değişkenini alabileceğimi biliyorum, ancak komutun tam olarak bash'de çalıştırmışım gibi davranmasının kolay bir yolu olup olmadığını merak ediyorum.
    2015-09-01 23: 17: 07Z
  2. @ KevinWheeler Bunun için shell=True kullanmanız gerekecek.
    2015-09-02 20: 38: 24Z
  3. @ KevinWheeler shell=True kullanmamalısınız, bu amaçla Python os.path.expandvars . Senin durumunda yazabilirsin: os.path.expandvars("$PATH"). @SethMMorton lütfen yorumunuzu tekrar gözden geçirin - > Neden kabuk kullanılmamalı = Doğru
    2015-11-11 20: 24: 27Z
  4. En azından kavramsal olarak basitleştirmek için: \n call ("ls -l" .split ())
    2018-06-16 17: 15: 48Z
  5. en azından python 3.5 gerektirdiğini söylemeyi unuttun. Örneğin, Ubuntu 14.04 LTS için varsayılan olan python 3.4.3'te çalışmaz.
    2019-02-02 22: 50: 04Z

    İşte harici programları çağırmanın yollarının ve her birinin avantaj ve dezavantajlarının bir özeti:

    1. 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:

       
      os.system("some_command < input_file | another_command > output_file")  
      

      Bununla birlikte, bu uygun olsa da, boşluklar, vb. gibi kabuk karakterlerinin kaçışını elle idare etmeniz gerekir. Öte yandan, bu aynı zamanda sadece harici komutlar yerine sadece kabuk komutları olan komutları çalıştırmanıza izin verir. belgelere bakın.

    2. stream = os.popen("some_command with args"), size erişmek için kullanabileceğiniz dosyaya benzer bir nesne vermesi dışında os.system ile aynı şeyi yaparBu işlem için andard giriş /çıkış. 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.

    3. Popen modülünün subprocess sınıfı. Bu, os.popen'un yerine geçecek şekilde tasarlandı, ancak çok kapsamlı olması nedeniyle biraz daha karmaşık olmanın dezavantajı var. Örneğin, şunu söylersiniz:

       
      print subprocess.Popen("echo Hello World", shell=True, stdout=subprocess.PIPE).stdout.read()
      

      yerine:

       
      print os.popen("echo Hello World").read()
      

      ancak tüm seçeneklerin 4 farklı popen işlevi yerine bir birleştirilmiş sınıfta olması güzel. belgelere bakın.

    4. call, subprocess modülünden çalışır. 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:

       
      return_code = subprocess.call("echo Hello World", shell=True)  
      

      belgelere bakın.

    5. Python 3.5 veya sonraki bir sürümündeyseniz, yeni subprocess.run işlevi, yukarıdakine çok benzeyen ancak daha da esnek bir işlevdir ve bir CompletedProcess komutu çalıştırmayı bitirdiğinde nesne.

    6. 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 şey olmalıdır.

    Son olarak, kabuğun bir karakter dizisi olarak çalıştırılacağı son komutu geçtiğiniz tüm yöntemlerde ve onu kaçmaktan sorumlu olduğunuzu unutmayın. İlettiğiniz dizenin herhangi bir kısmına tam olarak güvenilemiyorsa, Ciddi güvenlik uygulamaları 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:

     
    print subprocess.Popen("echo %s " % user_input, stdout=PIPE).stdout.read()
    

    ve kullanıcının tüm dosya sistemini silebilecek "annemin beni sevmediğini & rm-rf /" bir şey girdiğini hayal edin.

        
    2782
    2019-04-28 10: 57: 02Z
    1. 2015-05-26 21: 16: 27Z
    2. Python 3.5+ kullanıyorsanız, subprocess.run() kullanın. docs.python.org/3.5/library/subprocess.html#subprocess.
      koşmak
      2015-10-07 16: 37: 18Z
    3. Tipik olarak bilmesi gereken, çocuk sürecinin STDOUT ve STDERR'si ile yapılan şeydir, çünkü görmezden gelindiğinde, bazı (oldukça yaygın) koşullar altında, sonunda çocuk işlem, işletim sistemi tarafından işlem için sağlanan çıktı arabelleğini aşacak olan STDOUT'a (STDERR??) yazmak için bir sistem çağrısı düzenler ve işletim sistemi, bir işlem bu tampon belleğinden okuyana kadar engellemesine neden olur. Öyleyse, şu anda önerilen yöntemlerle subprocess.run(..), "Bu, varsayılan olarak stdout veya stderr'i yakalamaz." anlamına gelir? Peki ya subprocess.check_output(..) ve STDERR?
      2016-06-01 10: 44: 53Z
    4. @ Pitto evet, ancak örnek tarafından yürütülen bu değil. echo'a dize önüne geçen Popen'a dikkat edin. Yani tam komut echo my mama didnt love me && rm -rf / olacaktır.
      2018-09-10 16: 38: 25Z
    5. Thtartışmasız yanlış yoldur. Çoğu insan sadece subprocess.run() veya daha eski kardeşlerine ihtiyaç duyar subprocess.check_call() ve ark. Bunların yeterli olmadığı durumlarda subprocess.Popen()'a bakınız. os.popen() belki de hiç bahsedilmemeli, hatta "kendi çatal /exec /spawn kodunuzu hacklemeden" sonra bile gelmeli.
      2018-12-03 06: 00: 46Z

    Genelde kullanırım:

     
    import subprocess
    
    p = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    for line in p.stdout.readlines():
        print line,
    retval = p.wait()
    

    Boruda stdout verisiyle istediğiniz şeyi yapmakta serbestsiniz. Aslında, bu parametreleri (stdout= ve stderr=) atlayabilirsiniz ve os.system() gibi davranır.

        
    306
    2016-12-10 13: 22: 55Z
    1. .readlines(), bir kerede tüm satırları okur, yani alt işlem çıkana kadar engeller (borunun sonunu kapatır). Gerçek zamanlı okumak için (tamponlama sorunu yoksa) şunları yapabilirsiniz: for line in iter(p.stdout.readline, ''): print line,
      2012-11-16 14: 12: 18Z
    2. "Tamponlama sorunu yoksa" ile neyi kastediyorsunuz? İşlem kesinlikle engellerse, alt işlem çağrısı da engeller. Aynısı benim orijinal örneğimle de olabilir. Arabelleğe alma konusunda başka ne olabilir?
      2012-11-17 13: 25: 15Z
    3. alt işlem, satır arabelleği yerine etkileşimli olmayan modda blok arabelleği kullanabilir, böylece p.stdout.readline() (not: sonunda s no'lu veriler) hiçbir veri görmez Çocuk tamponunu dolduruncaya kadar. Çocuk çok fazla veri üretmezse, çıktı gerçek zamanlı olmayacaktır. İkinci nedene bakınız: S: Neden sadece bir boru kullanmıyorsunuz? (popen ())? . Bazı geçici çözümler, bu yanıtta verilmiştir (pexpect, pty, stdbuf)
      2012-11-17 13: 51: 25Z
    4. tamponlama sorunu yalnızca gerçek zamanlı olarak çıktı almak istiyorsanız ve tümü 'ye kadar hiçbir şey yazdırmayan kodunuz için geçerli değilse önemlidir veri alındı ​​
      2012-11-17 13: 53: 26Z
    5. Bu cevap zamanı için iyi oldu, ancak basit görevler için artık Popen'u önermemeliyiz. Bu da gereksiz yere shell=True'u belirtir. subprocess.run() cevaptan birini deneyin.
      2018-12-03 05: 39: 55Z

    Çocuk sürecini çağıran işlemden ayırma konusunda bazı ipuçları (çocuk işlemine arka planda başlama).

    Bir CGI betiğinden uzun bir görev başlatmak istediğinizi varsayalım; bu, alt işlemin CGI betiği yürütme işleminden daha uzun yaşaması gerektiğidir.

    Alt işlem modülü dokümanlarından klasik örnek:

     
    import subprocess
    import sys
    
    # some code here
    
    pid = subprocess.Popen([sys.executable, "longtask.py"]) # call subprocess
    
    # some more code here
    

    Buradaki fikir, longtask.py işlemi tamamlanıncaya kadar 'subprocess' çağrısı satırında beklemek istemeyeceğinizdir. Ancak, örneğin "burada biraz daha kod" satırından sonra ne olacağı belli değil.

    Hedef platformum freebsd idi, ancak geliştirme pencerelerdeydi, bu yüzden ilk önce pencerelerde sorunla karşılaştım.

    Pencerelerde (win xp), longtask.py çalışmasını bitirinceye kadar ana işlem bitmez. CGI-betiğinde istediğin bu değil. Sorun Python'a özgü değil, PHP topluluğunda da sorunlar aynı.

    Çözüm, DETACHED_PROCESS Win API'sındaki CreateProcess işlevinin temelini oluşturan Oluşturma Bayrağını İşleyin . Pywin32'yi kurduysanız, bayrağı win32process modülünden içe aktarabilirsiniz, aksi halde kendiniz tanımlamanız gerekir:

     
    DETACHED_PROCESS = 0x00000008
    
    pid = subprocess.Popen([sys.executable, "longtask.py"],
                           creationflags=DETACHED_PROCESS).pid
    

    /* 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 kanıtlanmış olduğunu gösterdim sys.stdout paylaşımında gibiydi. Ve çalışma çözümü şuydu:

     
    pid = subprocess.Popen([sys.executable, "longtask.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
    

    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şlemlerine başlamanın googlingi henüz bir ışık tutmuyor.

        
    196
    2017-07-27 21: 35: 57Z
    1. pydev + eclipse içinde py2exe uygulamaları geliştirirken olası bir "ilginçlik" fark ettim. eclipse'in çıkış penceresi sonlanmadığından ana betiğin çıkarılmadığını söyleyebildim; Senaryo tamamlanmaya çalışsa bile yine de iadeleri bekliyor. Ancak, bir py2exe çalıştırılabilir dosyasını derlemeye çalıştığımda, beklenen davranış ortaya çıkıyor (işlemleri ayrı olarak çalıştırıyor, sonra çıkıyor). Emin değilim, ancak yürütülebilir dosya artık işlem listesinde değil. bu tüm yaklaşımlar için işe yarar (os.system ("start *"), os.PaDL ile os.spawnl, subprocs, vs.)
      2010-04-09 08: 09: 26Z
    2. ayrıca CREATE_NEW_PROCESS_GROUP bayrağına da ihtiyaç duyabilirsiniz. Acil çocuk sona erdiğinde bile çocuk sürecini bekleyen Popen 'e bakın
      2012-11-16 14: 16: 42Z
    3. Aşağıdakiler yanlış: "[o] n pencereler (win xp), longtask.py çalışmasını bitirene kadar ana işlem bitmeyecek". Üst normal olarak çıkar, ancak konsol penceresi (conhost.exe örneği) yalnızca son eklenen işlem sona erdiğinde kapanır ve alt ebeveyn konsolunu devralmış olabilir. DETACHED_PROCESS’da creationflags’u ayarlamak, çocuğun bir konser miras almasını veya yaratmasını önleyerek bunu önler. Bunun yerine yeni bir konsol istiyorsanız, CREATE_NEW_CONSOLE (0x00000010) kullanın.
      2015-10-27 00: 27: 30Z
    4. Ayrılmış bir işlem olarak çalıştırmanın yanlış olduğu anlamına gelmiyordu. Bununla birlikte, bazı konsol programları başka bir hatayla çıktığından, standart tutamaçları dosyalara, borulara veya os.devnull'a ayarlamanız gerekebilir. Alt sürecin, üst işlemle aynı anda kullanıcıyla etkileşime girmesini istediğinizde yeni bir konsol oluşturun. Her ikisini de tek bir pencerede yapmayı denemek kafa karıştırıcı olabilir.
      2015-10-27 17: 37: 15Z
    5. , işlemin arka planda çalışmasını sağlamak için işletim sistemi için agnostik bir yol yok mu?
      2019-02-24 19: 05: 29Z

    os.system yerine subprocess modülünü kullanmanızı öneririm, çünkü sizin için kaçmayı önler ve bu nedenle çok daha güvenlidir: http://docs.python.org/library/subprocess.html

     
    subprocess.call(['ping', 'localhost'])
    
        
    120
    2014-04-04 19: 46: 08Z
    1. parametreli bir komuttan liste oluşturmak istiyorsanız , subprocess’da shell=False’da kullanılabilecek bir liste, sonra shlex.split’u kullanın. Bunu yapmanın kolay bir yolu için docs.python.org/2/library /shlex.html#shlex.split ( docs.python.org/2/library/subprocess.html#popen-constructor )
      2018-09-20 18: 07: 21Z
    2. Bu yanlıştır: " sizin için kaçan bir kabuk yapar ve bu nedenle çok daha güvenlidir ". subprocess kabuk kaçmayı yapmaz, subprocess komutunuzu kabuktan geçirmez, bu yüzden kabuk kaçmasına gerek yoktur.
      2018-12-04 08: 36: 35Z
     
    import os
    cmd = 'ls -al'
    os.system(cmd)
    

    Komutun sonuçlarını döndürmek istiyorsanız, os.popen . Ancak, bu sürüm 2.6 sürümünden beri alt işlem modülü 'nın lehine kaldırılmıştır. >, hangi diğer cevapların iyi ele aldığını.

        
    119
    2016-01-26 16: 53: 05Z
    1. popen alt işleme lehine kaldırılmıştır .
      2014-08-08 00: 22: 35Z
    2. Sonuç, os.system çağrısı ile de kaydedebilir, çünkü UNIX kabuğunun kendisi gibi çalışır, örneğin os.system ('ls -l > test2.txt ')
      2017-11-07 23: 19: 20Z
     
    import os
    os.system("your command")
    

    Komut 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.

        
    115
    2018-06-03 17: 10: 00Z
    1. "komut temizlenmedi" ile ne demek istiyorsun ?
      2018-06-03 17: 10: 31Z
    2. Neredeyse on yıl önce ne kastettiğimi bilmiyorum (tarihi kontrol et!), ama tahmin etmek zorunda olsaydım, onaylama yapılmamıştı.
      2018-06-06 16: 01: 34Z
    3. Bu şimdi subprocess'a biraz daha çok yönlü ve taşınabilir bir çözüm olarak göstermelidir. Dış komutları çalıştırmak elbette ki orantısızdır (desteklemeniz gereken her mimaride komutun kullanılabilir olduğundan emin olmanız gerekir) ve kullanıcı girişini harici bir komut olarak iletmek doğal olarak güvenli değildir.
      2018-12-03 05: 11: 39Z
    4. Bu adamdaki zaman damgasını not edin: "doğru" yanıt 40x oy aldı ve cevap # 1'dir.
      2018-12-03 18: 41: 52Z

    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 ls -l (tüm dosyaları listeler). Listelenen kütüphanelerden herhangi biri hakkında daha fazla bilgi edinmek ve bunların her birinin belgelerini bağlamanız gerekiyorsa.

      

    Kaynaklar:

      
        
          

    Bunların tümü kütüphanelerdir:

        
      

    Umarım bu, hangi kütüphaneyi kullanacağınıza karar vermenize yardımcı olur :)

      

    alt işlemi

    Alt işlem, harici komutları çağırmanıza ve bunları giriş /çıkış /hata borularına (stdin, stdout ve stderr) bağlamanıza olanak sağlar. Alt işlem çalışan komutlar için varsayılan seçimdir, ancak bazen diğer modüller daha iyidir.

     
    subprocess.run(["ls", "-l"]) # Run command
    subprocess.run(["ls", "-l"], stdout=subprocess.PIPE) # This will run the command and return any output
    subprocess.run(shlex.split("ls -l")) # You can also use the shlex library to split the command
    
      

    os

    os "işletim sistemine bağlı işlevsellik" için kullanılır. os.system ve os.popen ile harici komutları çağırmak için de kullanılabilir (Not: Ayrıca bir subprocess.popen vardır). os, kabuğu her zaman çalıştıracak ve subprocess.run'un nasıl kullanılacağını bilmeyen ya da nasıl kullanılacağını bilmeyen insanlar için basit bir alternatiftir.

     
    os.system("ls -l") # run command
    os.popen("ls -l").read() # This will run the command and return any output
    
      

    sh

    sh, programları sanki işlevmiş gibi çağırmanıza izin veren bir alt işlem arabirimidir. Bir komutu birden çok kez çalıştırmak istiyorsanız bu kullanışlıdır.

     
    sh.ls("-l") # Run command normally
    ls_cmd = sh.Command("ls") # Save command as a variable
    ls_cmd() # Run command as if it were a function
    
      

    plumbum

    plumbum, "script benzeri" Python programları için bir kütüphanedir. İşlevler gibi programları sh'daki gibi arayabilirsiniz. Plumbum, kabuksuz bir boru hattı çalıştırmak istiyorsanız kullanışlıdır.

     
    ls_cmd = plumbum.local("ls -l") # get command
    ls_cmd() # run command
    
      

    pexpect

    pexpect, alt uygulamalarınızı oluşturmanıza, kontrol etmenize ve çıktılarında kalıpları bulmanıza olanak sağlar. Bu, Unix'te bir tty bekleyen bir komut için alt işlemlere daha iyi bir alternatiftir.

     
    pexpect.run("ls -l") # Run command as normal
    child = pexpect.spawn('scp foo user@example.com:.') # Spawns child application
    child.expect('Password:') # When this is the output
    child.sendline('mypassword')
    
      

    kumaş

    kumaş Python 2.5 ve 2.7 kütüphanesidir. Yerel ve uzak kabuk komutlarını çalıştırmanıza izin verir. Yapı, komutları güvenli bir kabuk (SSH) içinde çalıştırmak için basit bir alternatiftir

     
    fabric.operations.local('ls -l') # Run command as normal
    fabric.operations.local('ls -l', capture = True) # Run command and receive output
    
      

    temsilcisi

    elçi "insanlar için alt süreç" olarak bilinir. subprocess modülünün etrafına kolaylık sarıcı olarak kullanılır.

     
    r = envoy.run("ls -l") # Run command
    r.std_out # get output
    
      

    komutları

    commands, os.popen için sarma işlevlerini içerir, ancak subprocess daha iyi bir alternatif olduğu için Python 3'ten kaldırılmıştır.

    Düzenleme, J.F. Sebastian'ın yorumuna dayanıyordu.

        
    72
    2017-05-28 23: 14: 34Z

    Bunun gibi şeyler için her zaman fabric kullanırım:

     
    from fabric.operations import local
    result = local('ls', capture=True)
    print "Content:/n%s" % (result, )
    

    Ancak bu iyi bir araç gibi görünüyor: sh (Python alt işlem arayüzü) .

    Bir örneğe bakın:

     
    from sh import vgdisplay
    print vgdisplay()
    print vgdisplay('-v')
    print vgdisplay(v=True)
    
        
    64
    2013-07-23 18: 28: 23Z

    "pexpect" Python kütüphanesini de kontrol edin.

    Harici programların /komutların, hatta ssh, ftp, telnet'in, vb. etkileşimli olarak denetlenebilmesini sağlar. Sadece şöyle bir şey yazabilirsiniz:

     
    child = pexpect.spawn('ftp 192.168.0.24')
    
    child.expect('(?i)name .*: ')
    
    child.sendline('anonymous')
    
    child.expect('(?i)password')
    
        
    63
    2017-05-28 23: 02: 27Z

    Aradığınız komutun çıktısına ihtiyacınız varsa, daha sonra subprocess.check_output (Python 2.7+) kullanabilirsiniz.

     
    >>> subprocess.check_output(["ls", "-l", "/dev/null"])
    'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'
    

    Ayrıca kabuk parametresini de not edin. p>

      

    Kabuk True ise, belirtilen komut kabuğun içinden yürütü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. Bununla birlikte, Python'un kendisinin birçok kabuk benzeri özelliğin uygulamalarını sunduğunu unutmayın (özellikle glob, fnmatch, os.walk(), os.path.expandvars(), os.path.expanduser() ve shutil).

        
    59
    2018-06-03 20: 18: 34Z
    1. check_output'un bir dize yerine bir liste gerektirdiğini unutmayın. Çağrınızı geçerli kılmak için alıntı yapılan alanlara güvenmiyorsanız, bunu yapmanın en basit ve okunaklı yolu subprocess.check_output("ls -l /dev/null".split())'dur.
      2018-01-30 18: 18: 54Z

    Standart Kütüphaneli

    alt işlem modülünü (Python 3) kullanın:

     
    import subprocess
    subprocess.run(['ls', '-l'])
    

    Önerilen standart yoldur. Ancak, daha karmaşık görevler (borular, çıktılar, girdi vb.) Oluşturmak ve yazmak için can sıkıcı olabilir.

    Python sürümüyle ilgili not: Hala Python 2 kullanıyorsanız, subprocess.call benzer şekilde çalışır.

    ProTip: shlex.split yardımcı olabilir istemiyorsanız (veya yapamazsanız!) bunları liste halinde sağlamanız durumunda, run, call ve diğer subprocess işlevlerinin komutunu ayrıştırabilirsiniz:

     
    import shlex
    import subprocess
    subprocess.run(shlex.split('ls -l'))
    

    Dış Bağımlılıklar ile

    Dış bağımlılıkları önemsemiyorsanız plumbum :

    kullanın  
    from plumbum.cmd import ifconfig
    print(ifconfig['wlan0']())
    

    En iyi subprocess sarıcıdır. Çapraz platform, yani hem Windows hem de Unix benzeri sistemlerde çalışıyor. pip install plumbum'a kadar yükleyin.

    Başka bir popüler kütüphane sh 'dir:

     
    from sh import ifconfig
    print(ifconfig('wlan0'))
    

    Ancak, sh Windows desteğini düşürdü, bu yüzden eskisi kadar harika değil. pip install sh'a kadar yükleyin.

        
    56
    2018-09-19 13: 55: 27Z

    Bu şekilde komutlarımı çalıştırıyorum. Bu kod, hemen hemen ihtiyacınız olan her şeye sahiptir

     
    from subprocess import Popen, PIPE
    cmd = "ls -l ~/"
    p = Popen(cmd , shell=True, stdout=PIPE, stderr=PIPE)
    out, err = p.communicate()
    print "Return code: ", p.returncode
    print out.rstrip(), err.rstrip()
    
        
    49
    2012-10-28 05: 44: 05Z
    1. Komutları dizge olarak geçirmek normalde kötü bir fikirdir
      2013-07-23 18: 29: 11Z
    2. Okunabilirliği arttırırsa kodlanmış komutlar için kabul edilebilir olduğunu düşünüyorum.
      2014-04-02 13: 07: 44Z

    Güncelleme:

    subprocess.run, önerilen yaklaşımdır Python 3.5'ten itibaren Kodunuzun önceki Python sürümleriyle uyumluluğu sürdürmesi gerekmez. Daha tutarlı ve Elçi ile benzer kullanım kolaylığı sunuyor. (Borular da bu kadar basit değildir. Bkz. bunun için nasıl bir soru ).

    İşte dokümanlar 'dan bazı örnekler:

    Bir işlem yürütün:

     
    >>> subprocess.run(["ls", "-l"])  # doesn't capture output
    CompletedProcess(args=['ls', '-l'], returncode=0)
    

    Başarısız olan çalıştırmada yükseltme:

     
    >>> subprocess.run("exit 1", shell=True, check=True)
    Traceback (most recent call last):
      ...
    subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
    

    Çıktıyı yakala:

     
    >>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
    CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
    stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')
    

    Orijinal cevap:

    Elçi 'yi denemeyi öneriyorum. Alt işlemler için bir sarmalayıcıdır; sırayla eski modül ve işlevleri değiştirmeyi hedefler . Elçi insanlar için alt süreçtir.

    benioku 'dan örnek kullanım:

     
    >>> r = envoy.run('git config', data='data to pipe in', timeout=2)
    
    >>> r.status_code
    129
    >>> r.std_out
    'usage: git config [options]'
    >>> r.std_err
    ''
    

    Boru parçaları da etrafta:

     
    >>> r = envoy.run('uptime | pbcopy')
    
    >>> r.command
    'pbcopy'
    >>> r.status_code
    0
    
    >>> r.history
    [<Response 'uptime'>]
    
        
    45
    2017-05-23 12: 26: 36Z

    Sonuç çıktısı olmadan:

     
    import os
    os.system("your command here")
    

    Sonucun çıktısıyla:

     
    import commands
    commands.getoutput("your command here")
    or
    commands.getstatusoutput("your command here")
    
        
    37
    2017-05-28 22: 59: 14Z
    1. commands Python 3'te artık kullanılamıyor. subprocess'dan os.system()'u tercih etmelisiniz
      2018-12-03 05: 33: 09Z

    https://docs.python.org/2/library/subprocess.html

    ... veya çok basit bir komut için:

     
    import os
    os.system('cat testfile')
    
        
    32
    2014-11-02 04: 00: 55Z

    Ayrıca Plumbum

    var  
    >>> from plumbum import local
    >>> ls = local["ls"]
    >>> ls
    LocalCommand(<LocalPath /bin/ls>)
    >>> ls()
    u'build.py\ndist\ndocs\nLICENSE\nplumbum\nREADME.rst\nsetup.py\ntests\ntodo.txt\n'
    >>> notepad = local["c:\\windows\\notepad.exe"]
    >>> notepad()                                   # Notepad window pops up
    u''                                             # Notepad window is closed by user, command returns
    
        
    30
    2014-10-10 17: 41: 13Z

    os.system tamam, ama biraz tarihli. Aynı zamanda çok güvenli değil. Bunun yerine, subprocess'u deneyin. subprocess doğrudan sh demez ve bu nedenle os.system'dan daha güvenlidir.

    Daha fazla bilgi edinin burayı .

        
    29
    2016-12-10 13: 25: 05Z
    1. Genel öneriyle aynı fikirde olduğum halde, subprocess tüm güvenlik sorunlarını ortadan kaldırmıyor ve sinir bozucu bazı sorunları var.
      2018-12-03 05: 36: 59Z
      

    Python'da harici bir komut çağırmak

    Basit, subprocess.run nesnesini döndüren CompletedProcess kullanın:

     
    >>> import subprocess
    >>> completed_process = subprocess.run('python --version')
    Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
    >>> completed_process
    CompletedProcess(args='python --version', returncode=0)
    

    Neden?

    Python 3.5'ten itibaren, belgeler subprocess.run :

      

    Alt işlemleri başlatmak 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ıma bir örnek - ve aynen istendiği gibi:

     
    >>> import subprocess
    >>> completed_process = subprocess.run('python --version')
    Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
    >>> completed_process
    CompletedProcess(args='python --version', returncode=0)
    

    run komutun başarıyla tamamlanmasını bekler, sonra CompletedProcess nesnesini döndürür. Bunun yerine TimeoutExpired (timeout= argümanı verirseniz) veya CalledProcessError (başarısız olursa ve check=True'u geçerseniz) yükseltebilir.

    Yukarıdaki örnekten anlaşılabileceği gibi, stdout ve stderr, varsayılan olarak kendi stdout'unuza ve stderr'inize aktarılır.

    Döndürülen nesneyi inceleyebilir ve verilen komutu ve dönüş kodunu görebiliriz:

     
    >>> completed_process.args
    'python --version'
    >>> completed_process.returncode
    0
    

    Çıktı yakalanıyor

    Çıkışı yakalamak istiyorsanız, subprocess.PIPE’u uygun stderr veya stdout’a geçirebilirsiniz:

     
    >>> cp = subprocess.run('python --version', 
                            stderr=subprocess.PIPE, 
                            stdout=subprocess.PIPE)
    >>> cp.stderr
    b'Python 3.6.1 :: Anaconda 4.4.0 (64-bit)\r\n'
    >>> cp.stdout
    b''
    

    (Sürüm bilgilerinin stdout yerine stderr'e konması ilginç ve biraz sezgiseldir.)

    Bir komut listesi iletin

    Bir program dizisi oluşturulmuş bir dize sağlamaya kolayca bir komut dizesi sağlamaktan (sorulanın önerdiği gibi) kolayca geçebilir. Dizeleri programlı olarak oluşturma. Bu potansiyel bir güvenlik sorunudur. Girdiye güvenmediğinizi varsaymak daha iyidir.

     
    >>> import textwrap
    >>> args = ['python', textwrap.__file__]
    >>> cp = subprocess.run(args, stdout=subprocess.PIPE)
    >>> cp.stdout
    b'Hello there.\r\n  This is indented.\r\n'
    

    Not, yalnızca args konumsal olarak geçilmelidir.

    Tam İmza

    İşte kaynaktaki ve help(run) ile gösterilen asıl imza:

     
    def run(*popenargs, input=None, timeout=None, check=False, **kwargs):
    

    popenargs ve kwargs, Popen yapıcısına verilir. input, alt işlemin stdinine yönlendirilecek olan bir bayt dizisi (veya kodlamayı belirtirseniz unicode veya universal_newlines=True) olabilir.

    Dokümantasyon, timeout= ve check=True’u benden daha iyi açıklıyor:

      

    Zaman aşımı argümanı Popen.communicate () öğesine iletilir. Zaman aşımı   süresi dolduğunda, çocuk işlemi öldürülecek ve beklenecek.   Alt işlem sona erdikten sonra TimeoutExpired özel durumu yeniden oluşturulacak   sonlandırıldı.

         

    Eğer kontrol doğruysa, bird işlem sıfır olmayan bir çıkış koduyla çıkarsa,   Denilen ProcessError istisnası oluşturulacak. Bunun öznitelikleri   kural dışı durum argümanları, çıkış kodunu ve eğer stdout ve stderr   yakalandılar.

    ve check=True için bu örnek, bulabileceğimden daha iyi:

     
    >>> subprocess.run("exit 1", shell=True, check=True)
    Traceback (most recent call last):
      ...
    subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
    

    Genişletilmiş İmza

    İşte belgelerde belirtildiği gibi genişletilmiş bir imza:

     
    subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, 
    shell=False, cwd=None, timeout=None, check=False, encoding=None, 
    errors=None)
    

    Bunun yalnızca arg listesinin konumsal olarak iletilmesi gerektiğini gösterdiğini unutmayın. Bu yüzden kalan değişkenleri anahtar kelime değişkenleri olarak iletin.

    POPEN

    Bunun yerine Popen kullanılır mı? Sadece tartışmalara dayanarak kullanım örneği bulmakta zorlanırdım. Bununla birlikte, Popen'un doğrudan kullanımı, poll, 'send_signal', 'sonlandır' ve 'bekle' gibi yöntemlerine erişmenizi sağlar.

    İşte kaynak 'da verilen Popen imzası >. Bunun, bilginin en kesin kapsüllenmesi olduğunu düşünüyorum (help(Popen)’un aksine):

     
    def __init__(self, args, bufsize=-1, executable=None,
                 stdin=None, stdout=None, stderr=None,
                 preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
                 shell=False, cwd=None, env=None, universal_newlines=False,
                 startupinfo=None, creationflags=0,
                 restore_signals=True, start_new_session=False,
                 pass_fds=(), *, encoding=None, errors=None):
    

    Ancak daha fazla bilgi verici olan Popen dokümantasyonu :

     
    subprocess.Popen(args, bufsize=-1, executable=None, stdin=None,
                     stdout=None, stderr=None, preexec_fn=None, close_fds=True,
                     shell=False, cwd=None, env=None, universal_newlines=False,
                     startupinfo=None, creationflags=0, restore_signals=True,
                     start_new_session=False, pass_fds=(), *, encoding=None, errors=None)
    
         

    Yeni bir işlemde bir alt program yürütün. POSIX’de, sınıf kullanır   os.execvp () - alt programı yürütme davranışına benzer. Windows'ta   sınıf, Windows CreateProcess () işlevini kullanır. Argümanlar   Popen şöyle:

    Kalan belgelerin Popen'da anlaşılması okuyucu için bir alıştırma olarak bırakılacaktır.

        
    28
    2017-10-18 16: 37: 52Z
    1. Bir birincil işlem ile bir alt işlem arasında iki yönlü iletişimin basit bir örneği burada bulunabilir: stackoverflow.com/a/52841475/1349673
      2018-10-16 18: 05: 17Z
    2. İlk örnekte muhtemelen shell=True olmalıdır veya (daha iyisi) komutu bir liste olarak iletin.
      2018-12-03 05: 16: 05Z

    Kullanım:

     
    import os
    
    cmd = 'ls -al'
    
    os.system(cmd)
    

    os - Bu modül işletim sistemine bağlı işlevselliği kullanmanın taşınabilir bir yolunu sunar.

    Daha fazla os işlevi için buradaki belgedir.

        
    25
    2017-05-28 23: 05: 23Z
    1. bu kullanımdan kaldırıldı. alt işlemi kullan
      2015-12-09 18: 13: 59Z

    Bu kadar basit olabilir:

     
    import os
    cmd = "your command"
    os.system(cmd)
    
        
    25
    2018-06-08 12: 06: 53Z
    1. Bu, PEP-324 . os.system belgeleri, açıkça subprocess lehine kaçınmayı önerir.
      2018-12-03 05: 02: 26Z

    os modülünü kullanın

     
    import os
    os.system("your command")
    

    örn

     
    import os
    os.system("ifconfig")
    
        
    21
    2018-07-27 08: 10: 20Z
    1. Bu, önceki nisandan (biraz) daha ayrıntılı bir yanıtı çoğaltır, ancak yine de uyarılara dikkat çekmez.
      2018-12-03 04: 59: 29Z

    subprocess.check_call, dönüş değerlerini test etmek istemiyorsanız uygundur. Herhangi bir hataya istisna atar.

        
    20
    2011-01-18 19: 21: 44Z

    alt işlem 'i çekişme (alıntılanan dizelerin kaçışını ele almak için):

     
    >>> import subprocess, shlex
    >>> command = 'ls -l "/your/path/with spaces/"'
    >>> call_params = shlex.split(command)
    >>> print call_params
    ["ls", "-l", "/your/path/with spaces/"]
    >>> subprocess.call(call_params)
    
        
    20
    2014-04-30 14: 37: 04Z

    Burada daha önce belirtilmeyen başka bir fark var.

    subprocess.Popen, < komutunu > bir alt işlem olarak. Benim durumumda, < a > bunun başka bir programla iletişim kurması gerekiyor, < b>.

    Alt işlemi denedim ve yürütme başarılı oldu. Bununla birlikte < b > < a > ile iletişim kuramadı. Her ikisini de terminalden çalıştırdığımda her şey normal.

    Bir tane daha: (NOT: kwrite diğer uygulamalardan farklı davranır. Aşağıdakini Firefox ile denerseniz, sonuç aynı olmaz.)

    os.system("kwrite")'u denerseniz, kullanıcı kwrite kapanana kadar program akışı donar. Bunun üstesinden gelmek için onun yerine 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 (örneğin, sistem monitöründe ağacın en sol kenarında görünmesi gerekir).

        
    20
    2018-06-03 20: 14: 32Z
    1. "ile kwrite alt işlem olmayan herkes çalışıyor" derken ne demek istiyorsun?
      2018-06-03 20: 14: 54Z

    os.system sonuçları saklamanıza izin vermiyor, bu nedenle sonuçları bir listede veya subprocess.call'un çalıştığı bir yerde saklamak istiyorsanız.

        
    19
    2012-06-11 22: 45: 35Z

    Sadeliği için shell_command 'ı çok seviyorum. Alt işlem modülünün üstüne inşa edilmiştir.

    İşte dokümanlardan bir örnek:

     
    >>> from shell_command import shell_call
    >>> shell_call("ls *.py")
    setup.py  shell_command.py  test_shell_command.py
    0
    >>> shell_call("ls -l *.py")
    -rw-r--r-- 1 ncoghlan ncoghlan  391 2011-12-11 12:07 setup.py
    -rw-r--r-- 1 ncoghlan ncoghlan 7855 2011-12-11 16:16 shell_command.py
    -rwxr-xr-x 1 ncoghlan ncoghlan 8463 2011-12-11 16:17 test_shell_command.py
    0
    
        
    19
    2017-10-24 19: 29: 34Z

    Utanmaz fiş, bunun için bir kütüphane yazdım: P https://github.com/houqp/shell.py

    Temelde şimdilik popen ve shlex için bir sarmalayıcı. Ayrıca, boru komutlarını da destekler, böylece Python'da komutları daha kolay zincirleyebilirsiniz. Böylece şöyle şeyler yapabilirsiniz:

     
    ex('echo hello shell.py') | "awk '{print $2}'"
    
        
    16
    2014-05-01 20: 49: 01Z

    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 edecek), görev biriktiricisi veya komutunda

    Görev biriktiricisine sahip bir örnek:

     
    import os
    os.system('ts <your-command>')
    

    Görev biriktiricisi hakkında notlar (ts):

    1. Çalıştırılacak eşzamanlı işlem sayısını ("yuvalar") şu şekilde ayarlayabilirsiniz:

      ts -S <number-of-slots>

    2. ts'u kurmak yönetici ayrıcalıkları gerektirmez. Basit bir make ile kaynaktan indirebilir ve derleyebilirsiniz, yolunuza ekleyin ve bitirdiniz.

    15
    2016-11-27 00: 15: 34Z
    1. ts bildiğim herhangi bir dağıtımda standart değildir, ancak at için işaretçi hafif yararlıdır. Muhtemelen batch'dan da bahsetmelisin. Başka bir yerde olduğu gibi, os.system() tavsiyesi muhtemelen en azından subprocess’un bunun yerine geçmesi gerektiğini belirtmelidir.
      2018-12-03 05: 43: 45Z

    Popen'ı kullanabilir ve ardından prosedürün durumunu kontrol edebilirsiniz:

     
    from subprocess import Popen
    
    proc = Popen(['ls', '-l'])
    if proc.poll() is None:
        proc.kill()
    

    subprocess.Popen adresini inceleyin.

        
    14
    2017-05-28 23: 01: 49Z
kaynak yerleştirildi İşte