Próbuję wykonać wywołanie systemowe w Pythonie i zapisać dane wyjściowe w ciągu znaków, którym mogę manipulować w programie Python.
#!/usr/bin/python
import subprocess
p2 = subprocess.Popen("ntpq -p")
Próbowałem kilku rzeczy, w tym niektórych sugestii tutaj:
Pobieranie danych wyjściowych z subprocess.call ()
ale bez powodzenia.
python
subprocess
znak
źródło
źródło
"ntpq -p"
, co jest inną częścią problem, o który pytasz.Odpowiedzi:
W Python 2.7 lub Python 3
Zamiast bezpośrednio tworzyć
Popen
obiekt, możesz użyćsubprocess.check_output()
funkcji do przechowywania danych wyjściowych polecenia w ciągu:W Pythonie 2.4-2.6
Skorzystaj z
communicate
metodyout
jest tym, czego chcesz.Ważna uwaga na temat innych odpowiedzi
Zwróć uwagę, jak przekazałem polecenie.
"ntpq -p"
Przykład wywołuje inna sprawa. PonieważPopen
nie wywołuje powłoki, użyłbyś listy poleceń i opcji—["ntpq", "-p"]
.źródło
Popen.communicate
nie zwraca, dopóki proces się nie zakończy.p = subprocess.Popen(["ntpq", "-p"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
subprocess.check_output()
zwracabytes
obiekt, a nie astr
. Jeśli wszystko, co chcesz zrobić, to wydrukować wynik, nie zrobi to żadnej różnicy. Ale jeśli chcesz użyć metody takiej jakmyString.split("\n")
wynik, musisz najpierw zdekodowaćbytes
obiekt:subprocess.check_output(myParams).decode("utf-8")
na przykład.universal_newlines=True
jako parametru pomogło mi w Pythonie 3 uzyskać obiekt string. Jeśli universal_newlines ma wartość True, są one otwierane w trybie tekstowym z domyślnym kodowaniem. W przeciwnym razie są one otwierane jako strumienie binarne.To działało dla mnie do przekierowywania standardowego wyjścia (stderr można obsługiwać w podobny sposób):
Jeśli to nie działa, proszę dokładnie określić problem.
źródło
\n
.pipe.returncode == 0
po ostatniej linii.Popen
zwraca krotkęstdout
istderr
, więc kiedy uzyskujesz dostęp[0]
, po prostu chwytaszstdout
. Możesz także zrobić,text, err = pipe.communicate()
a wtedytext
będziesz mieć to, czego oczekujeszZakładając, że
pwd
to tylko przykład, możesz to zrobić w następujący sposób:Zobacz dokumentację podprocesu, aby znaleźć inny przykład i więcej informacji.
źródło
subprocess.Popen: http://docs.python.org/2/library/subprocess.html#subprocess.Popen
W konstruktorze Popen, jeśli shell ma wartość True , należy przekazać polecenie jako ciąg, a nie sekwencję. W przeciwnym razie po prostu podziel polecenie na listę:
Jeśli chcesz przeczytać także błąd standardowy, w inicjalizacji Popena możesz ustawić stderr na podproces.PIPE lub podproces.STDOUT :
źródło
w przypadku Python 2.7+ idiomatyczną odpowiedzią jest użycie
subprocess.check_output()
Należy również zwrócić uwagę na obsługę argumentów podczas wywoływania podprocesu, ponieważ może to być nieco mylące ...
Jeśli args jest tylko jednym poleceniem bez własnych argumentów (lub
shell=True
ustawiłeś), może to być ciąg znaków. W przeciwnym razie musi to być lista.na przykład ... aby wywołać
ls
polecenie, w porządku:tak to jest:
jednak jeśli chcesz przekazać argumenty do polecenia powłoki, nie możesz tego zrobić:
zamiast tego musisz przekazać go jako listę:
shlex.split()
funkcja może być czasem przydatna podzielić ciąg do muszli-jak składni przed utworzeniem podprocesów ... tak:źródło
Działa to dla mnie idealnie:
źródło
To było dla mnie idealne. Otrzymasz kod powrotu, stdout i stderr w krotce.
Na przykład:
źródło
Przyjęta odpowiedź jest nadal dobra, tylko kilka uwag na temat nowszych funkcji. Od wersji Pythona 3.6 można bezpośrednio kodować
check_output
, patrz dokumentacja . Zwraca teraz obiekt ciągu:W python 3.7 dodano parametr
capture_output
do subprocess.run (), który wykonuje dla nas część obsługi Popen / PIPE, patrz dokumentacja python :źródło
W takim przypadku na liście będzie tylko jeden element.
źródło
os.popen
jest przestarzałe na korzyśćsubprocess
modułu.Napisałem małą funkcję na podstawie innych odpowiedzi tutaj:
Stosowanie:
źródło
W Pythonie 3.7 to nowy argument Hasło
capture_output
zostało wprowadzone dosubprocess.run
. Włączanie krótkiego i prostego:źródło
To rozwiązanie jednoliniowe
źródło
Poniżej przedstawiono stdout i stderr procesu w jednej zmiennej. Jest kompatybilny z Python 2 i 3:
Jeśli twoje polecenie jest ciągiem, a nie tablicą, poprzedz je:
źródło
Dla Pythona 3.5 uruchomiłem funkcję opartą na poprzedniej odpowiedzi. Dziennik może zostać usunięty. Pomyślałem, że dobrze go mieć
źródło
Użyj
ckeck_output
metodysubprocess
Na koniec przeanalizuj ciąg
Mam nadzieję, że to pomoże, szczęśliwego kodowania
źródło