Podproces Pythona.wywołanie i podproces.Popen stdout

Więc zauważyłem subprocess.call podczas gdy czeka na zakończenie polecenia przed kontynuacją skryptu Pythona, nie mam sposobu na uzyskanie stdout, z wyjątkiem subprocess.Popen. Czy są jakieś alternatywne wywołania funkcji, które czekałyby na zakończenie? (Próbowałem też Popen.wait)

UWAGA: staram się unikać os.system połączenia

result = subprocess.Popen([commands...,
                        self.tmpfile.path()], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = result.communicate()
print out+"HIHIHI"

Moje wyjście:

HIHIHI

UWAGA: próbuję uruchomić wine z tym.

Author: Stupid.Fat.Cat, 2012-11-15

4 answers

Używam poniższego konstruktu, chociaż możesz chcieć uniknąć shell=True. Daje to wyjście i Komunikat o błędzie dla dowolnego polecenia, a także kod błędu:

process = subprocess.Popen(cmd, shell=True,
                           stdout=subprocess.PIPE, 
                           stderr=subprocess.PIPE)

# wait for the process to terminate
out, err = process.communicate()
errcode = process.returncode
 55
Author: Alex,
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
2012-11-15 13:22:20
subprocess.check_output(...)

Wywołuje proces, podnosi jeśli jego kod błędu jest niezerowy, a w przeciwnym razie zwraca jego stdout. To tylko krótki Skrót, więc nie musisz się martwić o PIPE s I takie tam.

 14
Author: Katriel,
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
2012-11-15 13:31:25

Jeśli twój proces daje ogromne stdout i nie ma stderr, communicate() może to być zły sposób, aby przejść z powodu ograniczeń pamięci.

Zamiast

process = subprocess.Popen(cmd, shell=True,
                           stdout=subprocess.PIPE, 
                           stderr=subprocess.PIPE)

# wait for the process to terminate
for line in process.stdout: do_something(line)
errcode = process.returncode
/ Align = "left" /

process.stdout jest obiektem podobnym do pliku, który można traktować jako każdy inny tego typu obiekt, głównie:

  • możesz read() z niego
  • możesz readline() z niego i
  • możesz to powtórzyć.

Ten ostatni jest tym, co robię powyżej, aby uzyskać jego zawartość linia po linii.

 10
Author: glglgl,
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
2017-05-29 09:35:10

Spróbowałbym czegoś takiego:

#!/usr/bin/python
from __future__ import print_function

import shlex
from subprocess import Popen, PIPE

def shlep(cmd):
    '''shlex split and popen
    '''
    parsed_cmd = shlex.split(cmd)
    ## if parsed_cmd[0] not in approved_commands:
    ##    raise ValueError, "Bad User!  No output for you!"
    proc = Popen(parsed_command, stdout=PIPE, stderr=PIPE)
    out, err = proc.communicate()
    return (proc.returncode, out, err)

... Innymi słowy niech shlex.split() wykonuje większość pracy. Nie próbowałbym analizować linii poleceń powłoki, znaleźć operatorów rur i skonfigurować własnego rurociągu. Jeśli masz zamiar to zrobić, będziesz musiał napisać kompletny parser składni powłoki i skończysz robiąc strasznie dużo hydrauliki.

Oczywiście nasuwa się pytanie, dlaczego po prostu nie użyć Popen z opcją shell=True (słowo kluczowe)? To będzie pozwala przekazać ciąg znaków (bez dzielenia ani parsowania) do powłoki i nadal zbierać wyniki do obsługi, jak chcesz. Mój przykład tutaj nie przetworzy żadnych potoków, backtików, przekierowań deskryptorów plików itp., które mogą być w poleceniu, wszystkie będą wyświetlane jako dosłowne argumenty polecenia. W ten sposób jest jeszcze bezpieczniejsze, gdy działa z shell = True ... Podałem głupi przykład sprawdzania polecenia w jakimś słowniku "zatwierdzonym poleceniem" lub ustawionym - - - przez to zrobiłoby bardziej sensowne jest znormalizowanie tego w ścieżkę bezwzględną, chyba że zamierzasz wymagać, aby argumenty zostały znormalizowane przed przekazaniem ciągu poleceń do tej funkcji.

 1
Author: Jim Dennis,
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
2013-04-10 05:27:34