Popen ve çağrı alt süreçleri arasındaki fark nedir (bunları nasıl kullanabilirim)?


178

Python'dan harici bir program çağırmak istiyorum. Her ikisini de kullandım Popen()ve call()bunu yapmak için.

İkisi arasındaki fark nedir?

Benim özel amacım Python'dan aşağıdaki komutu çalıştırmak. Yönlendirmelerin nasıl çalıştığından emin değilim.

./my_script.sh > output

Belgeleri okudum ve bunun call()bir kolaylık işlevi veya bir kısayol işlevi olduğunu söylüyor . Bunun call()yerine kullanarak güç kaybeder miyiz Popen()?


Belgelerin hangi kısmı sizi şaşırttı? 'Nin tanımı call()çok açık görünüyor. Yanıtta neye odaklanacağımızı bilmemiz için bir teklif veya bağlantı sağlayabilir misiniz?
S.Lott

Yanıtlar:


265

Yönlendirmeyi yapmanın iki yolu vardır. Her ikisi de subprocess.Popenveya için geçerlidir subprocess.call.

  1. Anahtar kelime bağımsız değişkenini ayarlayın shell = Trueveya executable = /path/to/the/shellkomutu orada olduğu gibi belirtin.

  2. Çıktıyı bir dosyaya yeniden yönlendirdiğiniz için, anahtar kelime bağımsız değişkenini ayarlayın

    stdout = an_open_writeable_file_object

    burada nesne outputdosyayı gösterir.

subprocess.Popendaha geneldir subprocess.call.

Popenengellemez, çalışırken bu işlemle etkileşime girmenize veya Python programınızdaki diğer şeylerle devam etmenize olanak tanır. PopenBir Popennesneyi döndürme çağrısı .

call yapar bloğu. PopenYapıcı ile aynı argümanları desteklese de, yine de sürecin çıktısını, çevresel değişkenlerini vb. Ayarlayabilirsiniz, betiğiniz programın tamamlanmasını bekler callve sürecin çıkış durumunu temsil eden bir kod döndürür.

returncode = call(*args, **kwargs) 

temelde aramakla aynıdır

returncode = Popen(*args, **kwargs).wait()

callsadece bir kolaylık fonksiyonudur. CPython'daki uygulaması subprocess.py'de :

def call(*popenargs, timeout=None, **kwargs):
    """Run command with arguments.  Wait for command to complete or
    timeout, then return the returncode attribute.

    The arguments are the same as for the Popen constructor.  Example:

    retcode = call(["ls", "-l"])
    """
    with Popen(*popenargs, **kwargs) as p:
        try:
            return p.wait(timeout=timeout)
        except:
            p.kill()
            p.wait()
            raise

Gördüğünüz gibi, etrafta ince bir sargı var Popen.


17
Temel olarak Popen ve call asenkron ve senkronize fonksiyonlardır ve Linux komutlarını çalıştırırlar.
user3016020

1
Popen kullanmanın avantajı nedir? Aranan programın bitmesini beklemek güvenli olmaz mıydı?
Tom

4
@Tom Genellikle değil. Ya bazı çıktıları okumak, daha sonra programa daha fazla girdi göndermek, o girdiden kaynaklanan daha fazla çıktı okumak, tekrarlamak istiyorsanız?
agf

@ user3016020 Bunun Windows komutları için de geçerli olduğunu varsayıyorum? Sağ?
domih

7

Diğer cevap çok eksiksiz, ama işte bir kural:

  • call engelliyor:

    call('notepad.exe')
    print('hello')  # only executed when notepad is closed
  • Popen engellemiyor:

    Popen('notepad.exe')
    print('hello')  # immediately executed
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.