Jaka jest różnica między podprocesem Popen i call (jak mogę ich używać)?

178

Chcę wywołać zewnętrzny program z Pythona. Użyłem obu Popen()i call()do tego.

Jaka jest różnica między nimi?

Moim konkretnym celem jest uruchomienie następującego polecenia z Pythona. Nie wiem, jak działają przekierowania.

./my_script.sh > output

Przeczytałem dokumentację i mówi, że call()jest to funkcja wygoda lub funkcja skrótu. Czy tracimy jakąkolwiek moc, używając call()zamiast Popen()?

varunl
źródło
Jaka część dokumentacji wprowadziła Cię w zakłopotanie? Definicja call()wydaje się być bardzo jasna. Czy możesz podać cytat lub link, abyśmy wiedzieli, na czym należy się skupić w odpowiedzi?
S.Lott

Odpowiedzi:

265

Istnieją dwa sposoby wykonania przekierowania. Oba mają zastosowanie do jednego subprocess.Popenlub subprocess.call.

  1. Ustaw argument słowa kluczowego shell = Truelub executable = /path/to/the/shelli określ polecenie tak, jak je tam masz.

  2. Ponieważ po prostu przekierowujesz dane wyjściowe do pliku, ustaw argument słowa kluczowego

    stdout = an_open_writeable_file_object

    gdzie obiekt wskazuje na outputplik.

subprocess.Popenjest bardziej ogólny niż subprocess.call.

Popennie blokuje, umożliwiając interakcję z procesem podczas jego działania lub kontynuowanie innych rzeczy w programie w języku Python. Wezwanie doPopen zwraca Popenobiekt.

call robi blok. Chociaż obsługuje wszystkie te same argumenty co Popenkonstruktor, więc nadal możesz ustawić dane wyjściowe procesu, zmienne środowiskowe itp., Twój skrypt czeka na zakończenie programu icall zwraca kod reprezentujący stan wyjścia procesu.

returncode = call(*args, **kwargs) 

to w zasadzie to samo, co dzwonienie

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

callto tylko funkcja zapewniająca wygodę. Jego implementacja w CPythonie znajduje się w subprocess.py :

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

Jak widać, jest to cienkie opakowanie Popen.

agf
źródło
17
Zasadniczo Popen i call to funkcje asynchroniczne i synchroniczne, odpowiednio używane do uruchamiania poleceń Linuksa.
user3016020
1
Jaka jest zaleta używania popenu? Czy nie byłoby bezpiecznie poczekać, aż wywołany program zakończy się jako pierwszy?
Tom
4
@Tom Często nie. A jeśli chcesz przeczytać jakieś dane wyjściowe, a następnie wysłać więcej danych wejściowych do programu, przeczytać więcej wyników, które wynikają z tego wejścia, powtórz?
agf
@ user3016020 Zakładam, że dotyczy to również poleceń systemu Windows? Dobrze?
domih
7

Druga odpowiedź jest bardzo kompletna, ale oto praktyczna zasada:

  • call blokuje:

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

    Popen('notepad.exe')
    print('hello')  # immediately executed
Basj
źródło