Jest to kontynuacja poprzedniego artykułu dotyczącego Pythona w Linuksie. W tym powinieneś już wiedzieć, w jaki sposób stworzyć oraz uruchomić skrypt. Jak również powinny być znane pozostałe elementy języka omówione w poprzednim materiale. Dlatego jeżeli jeszcze nie czytałeś kliknij tutaj. A teraz czas ma język Python w systemie Linux – część 2.

Dość obszerny wstęp znajdował się w części pierwszej. Dlatego w tej od razu przejdziemy do części praktycznej.

 

Zapis na newsletter!

Zanim jednak rozwinę temat dalej to jedna informacja na początek. Prowadzę regularny, cotygodniowy newsletter z poradami związanymi z Zabbixem, monitoringiem oraz dobrymi praktykami w IT. Jeżeli nie chcesz przegapić kolejnych części oraz zaproszeń na nasze darmowe szkolenia to zapraszam do zapisu. Wystarczy pobrać mój poradnik. Monitoring IT – Dobre Praktyki. Wystarczy wejść klikając na obrazek:

__________________________________________

 

Język Python w systemie Linux – biblioteki i polecenia Linux

Administracja w systemie Linux głównie opiera się na wykonywaniu poleceń systemowych. Jesteśmy również często zmuszeni do ręcznej modyfikacji plików konfiguracyjnych. Wymieniać czynności jakie administrator systemowy musi wykonać można wyliczać w nieskończoność. Natomiast celem artykułów związanych z Pythonem jest pokazać podstawy tego języka i jak je wykorzystać w celu zautomatyzowania niektórych zadań.

W języku Python występują biblioteki, które deklarujemy na samym początku pliku. W tych bibliotekach znajdują się instrukcje, dzięki którym możemy wykonywać różnego rodzaju czynności w prostszy sposób. Nas będzie interesowała biblioteka, która umożliwi wywołanie poleceń systemowych. W języku Python taka nosi nazwę subprocess. Aby móc z niej korzystać, to musi pojawić się jej deklaracja w naszym skrypcie. Biblioteki są dodawane w następujący sposób:

import subprocess

Dzięki instrukcji import do naszego pliku dodajemy bibliotekę z instrukcjami, które umożliwiają korzystanie z poleceń systemowych Linux. Otóż, my dostęp do tych poleceń mamy od samego początku, nawet bez dodania biblioteki. Jednak, aby z nich skorzystać, musielibyśmy napisać sporą ilość kodu. Biblioteka zawiera wspomnianą sporą ilość kodu, dzięki któremu większość czynności jesteśmy w stanie wykonać przy użyciu jednej lub kilku linii. Dlatego, aby skorzystać z polecenia nie musimy pisać n ilości tylko korzystamy z instrukcji opracowanych i zawartych we wskazanej bibliotece.

Kiedyś jeżeli będziesz chciał zagłębić się w ten język możliwe, że sam napiszesz takie biblioteki. Natomiast na ten moment ustalamy, że dzięki tej bibliotece w łatwy sposób jesteśmy w stanie użyć poleceń systemowych. Stwórzmy prosty skrypt jak w poniższym przykładzie:

#!/usr/bin/env python3

import subprocess

# pierwszy przykład polecenia do wywoływania poleceń w systemie Linux

subprocess.call("uname -a", shell=True)

Skrypt nazwałem trzy.py, ponieważ jest to nasz trzeci skrypt z dotychczasowych artykułów. Uruchommy go:

python3 trzy.py
Linux noishacking 5.10.0-19-amd64 #1 SMP Debian 5.10.149-2 (2022-10-21) x86_64 GNU/Linux

Aby wywołać polecenie musimy posłużyć się instrukcją subprocess.call. To, co znajduje się przed kropką to nazwa biblioteki. Natomiast to, co po kropce jest to nazwa funkcji, która występuje we wskazanej bibliotece. W funkcji znajdują się instrukcje, dzięki którym jesteśmy, poprzez przekazanie parametrów, je wywołać. Na samym końcu musimy ustawić opcję shell (powłokę) na wartość True, jeżeli chcemy używać poleceń z opcjami. Bez tego możemy korzystać tylko z poleceń jednowyrazowych. Do tematu funkcji na pewno jeszcze wrócimy i będziemy pisali własne.

W związku z tym możemy na przykład przeprowadzić aktualizacje systemu uzupełniając instrukcję w następujący sposób:

subprocess.call("sudo apt update && sudo apt dist-upgrade -y", shell=True)

Gdy uruchomisz skrypt, zostaną pobrane najnowsze repozytoria. Następnie wykonana aktualizacja systemu. Niestety, ten sposób nas ogranicza do systemów opartych o menadżer pakietów apt.

Przekazywanie argumentów

Ograniczenie przedstawione w poprzednim skrypcie jest problemem. Możesz korzystać z systemu Red Hat gdzie menadżerem pakietów jest yum i dnf. Oczywiście, możesz dokonać zmian w kodzie, ale nie o to tutaj chodzi. Szczególnie, że w przypadku, gdy będziemy posiadali bardzo rozbudowany skrypt dokonanie takich zmian może okazać się problemem. I tu z pomocą przychodzi możliwość przekazywania argumentów.

W linii poleceń systemu Linux bardzo często korzystasz z tej metody. W pierwszym skrypcie tego artykułu skorzystaliśmy z polecenia:

uname -a

Do polecenia uname przekazaliśmy argument -a ustawiający polecenie do wyświetlenia odpowiedniego komunikatu. My, wykorzystując możliwość przekazywaniu argumentów prześlemy informację skryptowi z jakiego menadżera pakietów chcemy skorzystać.

Tak jak w przypadku możliwości korzystania z poleceń systemowych, tak i w tym musimy dodać odpowiednią bibliotekę. Dlatego pod biblioteką subrocess dodajemy:

import argparse

Biblioteką odpowiadającą za przekazywanie argumentów w Pythonie 3 jest argparse. Jak zapewne wiesz, dodanie samej biblioteki nic nam nie da, dlatego zobaczmy co możemy z tym zrobić. Zerknij na poniższy kod:

#!/usr/bin/env python3

import subprocess

import argparse

system = argparse.ArgumentParser()

system.add_argument("-s", "--system", dest="nasza_dystrybucja", help="podajemy nazwę naszej dystrybucji")

opcje = system.parse_args()

print(opcje.nasza_dystrybucja)

# pierwszy przykład polecenia do wywoływania poleceń w systemie Linux

#subprocess.call("sudo apt update && sudo apt dist-upgrade -y", shell=True)

Początek jest taki sam jak dotychczas. Natomiast w dalszej części przechodzimy do stworzenia możliwości korzystania z przechwycenia tego co przekażemy przy uruchomieniu skryptu.

Na początku tworzymy zmienną o nazwie system.

Do niej przypisujemy wartość umożliwiającą ustawienie opcji przy ich wywołaniu.

system = argparse.ArgumentParser()

Pisząc prościej, to w tej zmiennej będą przechowywane wszystkie dostępne argumenty z jakich możemy skorzystać przy wywołaniu polecenia. Tutaj stosujemy podobną zasadę jaką poznaliśmy poprzednio. Tylko, że naszą zmienną system ustawiliśmy jako obiekt biblioteki argparse. Natomiast poprzednio wywołaliśmy od razu obiekt z biblioteki. Różnica jest taka, że ostatnio zostały wywołane instrukcje od razu, natomiast tym razem do naszej zmiennej dodaliśmy wszystkie możliwości jakie posiada biblioteka argparse, ale ich nie wywołaliśmy. W związku z tym wszystkie funkcje jakie wywołamy zostaną zapisane w niej.

system.add_argument("-s", "--system", dest="nasza_dystrybucja", help="nazwa naszej dystrybucji")

Zerknij na tę część kodu. Stosujemy nazwę naszej zmiennej, której poprzednio daliśmy możliwość korzystania z wszystkich dostępnych funkcji biblioteki. Po kropce stosujemy jedną z dostępnych funkcji służącą do dodawania argumentów przy uruchomieniu skryptu.

W pierwszym członie ustawiłem -s. Jest to nazwa opcji stosowana jako skrócona. Bezpośrednio po niej występuje jej rozwinięta nazwa –system. W dest ustawiamy nazwę pod jaką będzie dostępna wartość opcji. Na samym końcu podajemy opis, że po wywołaniu -h pojawi się ta informacja.

opcje = system.parse_args()

Zmiennej opcje przekazujemy argumenty dzięki czemu możemy z nich skorzystać w następujący sposób:

print(opcje.nasza_dystrybucja)

Skorzystaliśmy ze zmiennej opcja i po kropce wpisaliśmy nazwę którą ustawiliśmy w dest -s.

Pozostałą część objąłem w pojedynczy komentarz, ponieważ tamta część działa i w obecnej chwili nie ma potrzeby jej uruchamiać.

Uruchommy nasz skrypt:

python3 trzy.py -s debian

debian

Drugi sposób to:

python3 trzy.py --system debian

debian

Natomiast pomoc do naszego polecenia możemy uzyskać wpisując:

python3 trzy.py -h

usage: trzy.py [-h] [-s NASZA_DYSTRYBUCJA]

optional arguments:

  -h, --help            show this help message and exit

  -s NASZA_DYSTRYBUCJA, --system NASZA_DYSTRYBUCJA

                        nazwa naszej dystrybucji

Wygląda ciekawie. Poznaliśmy sposób, w jaki możemy pobrać to, co przekazaliśmy przy wywołaniu polecenia. Zobaczmy, co z tym dalej możemy zrobić.

Instrukcje warunkowe

Mamy już informację, że korzystamy z systemu Debian. Teraz musimy to w jakiś rozsądny sposób przetworzyć tak, abyśmy mogli wykorzystać. Pierwszym rozwiązaniem będą instrukcje warunkowe. Pozwalają one podjąć decyzję co ma się wykonać jeżeli wystąpi dana sytuacja. Nim przejdę do dalszego opisu zerknijmy ponownie na kod:

#!/usr/bin/env python3

import subprocess

import argparse

system = argparse.ArgumentParser()

system.add_argument("-s", "--system", dest="nasza_dystrybucja", help="podajemy nazwę naszej dystrybucji")

opcje = system.parse_args()

if opcje.nasza_dystrybucja == 'debian':

      menadzer_pakietow = 'apt'

elif opcje.nasza_dystrybucja == 'red hat':

      menadzer_pakietow = 'yum'

else:

      menadzer_pakietow = 'błąd'

print(menadzer_pakietow)     

# pierwszy przykład polecenia do wywoływania poleceń w systemie Linux

#subprocess.call("sudo apt update && sudo apt dist-upgrade -y", shell=True)

Zaczniemy od miejsca, w którym skończyliśmy. Pojawiła się instrukcja składająca się z if elif oraz else. W niej przy pierwszych dwóch etykietach wykonujemy porównanie przekazanego argumentu z wybraną przez nas wartością. Ta sytuacja ma miejsce zarówno w if i elif. Jeżeli wynik porównania jest True, czyli prawdziwy to zostaje do zmiennej przypisana wartość apt. Jeżeli wprowadziłeś jako argument red hat, yum. W przypadku jeżeli żadna z wartości nie odpowiada wykonanym dwóm porównaniom, to przyjmowana jest wartość False. W tej sytuacji instrukcja przechodzi do etykiety else, w której przypisujemy wartość „błąd”. Ostatnia opcja jest zatem wykonywana w sytuacji, kiedy w dwóch poprzednich wynik porównania jest nieprawdziwy. Czyli wywołana będzie, gdy wartość przekazana nie będzie odpowiadała wartości debian lub red hat.

Tutaj zwróć uwagę. Porównania dokonujemy przy pomocy dwóch znaków równa się ==. Natomiast przypisania przy pomocy jednego znaku =. Zapamiętaj tę zasadę. Ja na przykład czasami nadal o tym zapominam.

Kolejnym ważnym elementem instrukcji i ogólnie całego Pytona, są zastosowane wcięcia. Zerknijmy na część kodu:

if opcje.nasza_dystrybucja == 'debian':

      menadzer_pakietow = 'apt'

Jeżeli chcemy, żeby do zmiennej menadżer_pakietow została przypisana wartość apt, to musi zostać wykonane wcięcie tak jak w prezentowanym przykładzie. Pamiętaj jednak, że apt zostanie przypisana jedynie w przypadku gdy wartość porównania będzie prawdziwa czyli True. Natomiast jeżeli menadżer pakietów byłby kolejną instrukcją od której coś zależy to takie wcięcia powinny pojawić się również, ale w stosunku do menadżera pakietów. Bardziej logicznie to można rozpisać w następujący sposób:

Instrukcja 1:

      Instrukcja2:

            Instrukcja3:

      Instrukcja4:

Mamy cztery instrukcje. Instrukcja 1 bezpośrednio dotyczy Instrukcji 2 oraz Instrukcji 4. Natomiast Jeżeli Instrukcja 2 będzie posiadała wartość True zostanie wykonana Instrukcja 3. Natomiast jeżeli Instrukcja 2 będzie posiadała wartość True to już Instrukcja 4 nie będzie wywołana.

Użycie otrzymanego wyniku przy poleceniu systemowym

Mamy już instrukcje warunkową, która określiła z jakiego menadżera pakietów korzysta nasz system. Teraz zobaczmy w jaki sposób taką informację jesteśmy w stanie wykorzystać w naszym skrypcie.

subprocess.call("sudo " + menadzer_pakietow + " update && sudo " + menadzer_pakietow + " dist-upgrade -y", shell=True)

Wkleiłem tylko tę instrukcję ponieważ pozostałe elementy pozostaną bez zmian. Zmienną, która posiada nazwę naszego menadżera pakietów dodajemy do polecenia przy użyciu znaku matematycznego +. Pamiętaj jeszcze o tym, że przed i po zmiennej musimy użyć spacji. Jeżeli tego nie zrobimy to polecenie się nie wywoła. Zresztą zawsze możesz tych spacji nie zrobić i zobaczysz co się stanie.

Teraz jeżeli wywołasz polecenie wykona ono aktualizacje systemu. Jednak pamiętaj, jeżeli korzystasz z argumentu zawierającego więcej niż jeden wyraz musisz go objąć w nawias. Tak jak w poniższym przykładzie:

python3 trzy.py -s 'red hat'

Język Python w systemie Linux – podsumowanie

Dzięki materiałom z tego artykułu, czyli „Język Python w systemie Linux” poznałeś dwie bardzo użyteczne biblioteki. Wszystkie możliwości powiązane z tym co do tej pory przeczytałeś rozwiniemy w pozostałych artykułach. Od razu dopiszę, kod nie jest idealny. Powinien być w dość mocny sposób zmodyfikowany. Natomiast na poziomie na jakim obecnie jesteśmy musi wystarczyć. Z czasem będziemy go modyfikować, aż stanie się bardziej użyteczny i będzie lepszy pod względem rozbudowy.

Chcesz więcej?

Oczywiście, jeżeli nie chcesz przegapić tego typu materiałów, to zapisz się na mój newsletter i przy okazji odbierz darmowe bonusy, np. e-booka ze zdjęcia poniżej! Prowadzę regularny, cotygodniowy newsletter z poradami związanymi z automatyzacją, monitoringiem oraz dobrymi praktykami w IT.

Zapisy TUTAJ

Zapisz się na Newsletter i odbierz za darmo e-book "Monitoring IT"!

X