Jaka jest różnica między podprocesem Popen a call(Jak mogę ich użyć)?

Chcę wywołać zewnętrzny program z Pythona. Użyłem do tego zarówno Popen(), jak i call().

Jaka jest różnica między nimi?

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

./my_script.sh > output

Przeczytałemdokumentację i mówi, że call() jest funkcją wygodną lub funkcją skrótu. Czy tracimy jakąkolwiek moc używając call() zamiast Popen()?

Author: nbro, 2011-10-06

2 answers

Są dwa sposoby na przekierowanie. Oba dotyczą subprocess.Popen lub subprocess.call.

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

  2. Ponieważ tylko przekierowujesz wyjście do pliku, Ustaw argument słowa kluczowego

    stdout = an_open_writeable_file_object
    

    Gdzie obiekt wskazuje na plik output.

subprocess.Popen jest bardziej ogólny niż subprocess.call.

Popen nie blokuje, pozwalając aby wchodzić w interakcje z procesem podczas jego działania lub kontynuować inne czynności w programie Pythona. Wywołanie Popen zwraca obiekt Popen.

call czy blokuje. Mimo że obsługuje wszystkie te same argumenty co konstruktor Popen, możesz więc nadal ustawić wyjście procesu, zmienne środowiskowe itp., Twój skrypt czeka na zakończenie programu, a call zwraca kod reprezentujący status zakończenia procesu.

returncode = call(*args, **kwargs) 

Jest w zasadzie tym samym co wywołanie

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

call to tylko Funkcja wygodna. To implementacja w Cpythonie jest 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 widzisz, to cienka owijka wokół Popen.

 276
Author: agf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-07 00:07:10

Druga odpowiedź jest bardzo kompletna, ale tutaj jest zasada:

  • call blokuje:

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

    Popen('notepad.exe')
    print('hello')  # immediately executed
    
 18
Author: Basj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-06 16:45:14