Jak wykonywać polecenia powłoki w Pythonie za pomocą metody uruchamiania podprocesu

How Execute Shell Commands Python Using Subprocess Run Method



Subprocess to wbudowany moduł Pythona, który może być używany do tworzenia nowych procesów i interakcji z ich wejściowymi i wyjściowymi strumieniami danych. Mówiąc prościej, można go używać do uruchamiania poleceń powłoki i uruchamiania wykonywalnych plików binarnych, zwykle rozproszonych w różnych folderach bin w systemie plików Linux. Możesz również podać pełną ścieżkę do wykonywalnego pliku binarnego i użyć dowolnych przełączników wiersza polecenia skojarzonych z plikiem binarnym. W tym artykule wyjaśnimy, jak korzystać z modułu subprocess i jego metody uruchamiania w aplikacjach Pythona. Wszystkie próbki kodu w artykule są testowane w Pythonie 3.8.2 na Ubuntu 20.04.

Metoda Subprocess.run

Metoda Subprocess.run pobiera listę argumentów. Gdy metoda jest wywoływana, wykonuje polecenie i czeka na zakończenie procesu, zwracając na końcu obiekt CompletedProcess. Obiekt CompletedProcess zwraca stdout, stderr, oryginalne argumenty używane podczas wywoływania metody oraz kod powrotu. Stdout odnosi się do strumienia danych generowanego przez polecenie, podczas gdy stderr odnosi się do wszelkich błędów zgłoszonych podczas wykonywania programu. Każdy niezerowy kod powrotu (kod wyjścia) oznaczałby błąd z poleceniem wykonanym w metodzie subprocess.run.







Przykład 1: Wyjście zawartości pliku tekstowego przy użyciu metody Subprocess.run

Poniższe polecenie wyświetli zawartość pliku data.txt, zakładając, że zawiera on ciąg name=John.



import podproces
podproces.biegać(['Kot', 'dane.txt'])

Uruchomienie powyższego kodu zwróci następujące dane wyjściowe:



Nazwa=Jan
Ukończony proces(argumenty=['Kot', 'dane.txt'],kod powrotu=0)

Pierwszym elementem argumentu list jest nazwa polecenia do wykonania. Każdy element na liście, który następuje po pierwszym elemencie, jest uważany za opcje lub przełączniki wiersza polecenia. Do zdefiniowania opcji można również użyć pojedynczych i podwójnych myślników. Na przykład, aby wyświetlić listę plików i folderów w katalogu, kod powinien wyglądać tak: subprocess.run([ls, -l]. W większości przypadków każdy argument oddzielony spacjami w poleceniu powłoki można traktować jako oddzielny element w lista dostarczona do metody subprocess.run.





Przykład 2: Pomiń dane wyjściowe metody Subprocess.run

Aby pominąć dane wyjściowe metody subprocess.run, musisz podać stdout=subprocess.DEVNULL i stderr=subprocess.DEVNULL jako dodatkowe argumenty.

import podproces

podproces.biegać(['Kot', 'dane.txt'],stdout=podproces.DEVNULL,
stderr=podproces.DEVNULL)

Uruchomienie powyższego kodu da następujące dane wyjściowe:



CompletedProcess(args=['cat', 'data.txt'], returncode=0)

Przykład 3: Przechwytywanie danych wyjściowych metody Subprocess.run

Aby przechwycić dane wyjściowe metody subprocess.run, użyj dodatkowego argumentu o nazwie capture_output=True.

import podproces
wyjście= podproces.biegać(['Kot', 'dane.txt'],przechwytywanie_wyjście=Prawdziwe)
wydrukować (wyjście)

Uruchomienie powyższego kodu da następujące dane wyjściowe:

Ukończony proces(argumenty=['Kot', 'dane.txt'],kod powrotu=0,
stdout=b'imię=Jan ',stderr=b'')

Dostęp do wartości stdout i stderr można uzyskać indywidualnie za pomocą metod output.stdout i output.stderr . Dane wyjściowe są generowane jako sekwencja bajtów. Aby uzyskać ciąg znaków jako wynik, użyj metody output.stdout.decode(utf-8). Możesz również podać text=True jako dodatkowy argument do wywołania subprocess.run, aby uzyskać dane wyjściowe w formacie ciągu. Aby uzyskać kod statusu wyjścia, możesz użyć metody output.returncode.

Przykład 4: Zgłoś wyjątek w przypadku niepowodzenia polecenia wykonanego przez metodę Subprocess.run

Aby zgłosić wyjątek, gdy polecenie kończy działanie z niezerowym statusem, użyj argumentu check=True.

import podproces
podproces.biegać(['Kot', „dane.txt”],przechwytywanie_wyjście=Prawdziwe,tekst=Prawdziwe,sprawdzać=Prawdziwe)

Uruchomienie powyższego kodu da następujące dane wyjściowe:

podnieś CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Polecenie '['cat', 'data.tx']'
zwrócono niezerowy status wyjścia 1.

Przykład 5: Przekaż ciąg do polecenia wykonanego przez metodę Subprocess.run

Możesz przekazać ciąg do polecenia, które ma zostać wykonane przez metodę subprocess.run, używając argumentu input='string'.

import podproces
wyjście= podproces.biegać(['Kot'], Wejście='dane.txt',przechwytywanie_wyjście=Prawdziwe,
tekst=Prawdziwe,sprawdzać=Prawdziwe)
wydrukować (wyjście)

Uruchomienie powyższego kodu da następujące dane wyjściowe:

CompletedProcess(args=['cat'], returncode=0, stdout='data.txt', stderr='')

Jak widać, powyższy kod przekazuje data.txt jako ciąg, a nie jako obiekt pliku. Aby przekazać data.txt jako plik, użyj argumentu stdin.

z otwarty('dane.txt') jakF:
wyjście= podproces.biegać(['Kot'],stdin=F,przechwytywanie_wyjście=Prawdziwe,
tekst=Prawdziwe,sprawdzać=Prawdziwe)
wydrukować (wyjście)

Uruchomienie powyższego kodu da następujące dane wyjściowe:

CompletedProcess(args=['cat'], returncode=0, stdout='name=Jan ', stderr='')

Przykład 6: wykonanie polecenia bezpośrednio w powłoce przy użyciu metody Subprocess.run

Możliwe jest uruchomienie polecenia bezpośrednio w powłoce, tak jak jest, zamiast używania łańcucha podzielonego w głównym poleceniu i następujących po nim opcjach. Aby to zrobić, musisz przekazać shell=True jako dodatkowy argument. Jest to jednak odradzane przez programistów Pythona, ponieważ użycie powłoki = True może prowadzić do problemów z bezpieczeństwem. Możesz przeczytać więcej o wpływie na bezpieczeństwo z tutaj .

import podproces
podproces.biegać('kot 'dane.txt'',powłoka=Prawdziwe)

Uruchomienie powyższego kodu da następujące dane wyjściowe:

imię=Jan

Wniosek

Metoda subprocess.run w Pythonie jest dość potężna, ponieważ pozwala na uruchamianie poleceń powłoki w samym Pythonie. Pomaga to w ograniczeniu całego kodu do samego Pythona bez konieczności posiadania dodatkowego kodu skryptu powłoki w osobnych plikach. Prawidłowe tokenizowanie poleceń powłoki na liście Pythona może być jednak dość trudne. Możesz użyć metody shlex.split() do tokenizacji prostych poleceń powłoki, ale w długich, złożonych poleceniach – zwłaszcza tych z symbolami potoku – shlex nie może poprawnie podzielić polecenia. W takich przypadkach debugowanie może być trudnym problemem. Możesz użyć argumentu shell=True, aby tego uniknąć, ale z tą akcją wiążą się pewne problemy związane z bezpieczeństwem.