Terminalowe herezje: sprawdzamy, ile jest wart PowerShell 7 na Linuksa
Microsoft bez ustanku rozwija nowe, wieloplatformowe oblicza swoich środowisk programistycznych. Poza niemal ukończonym już frameworkiem .NET Core 3.0, wkrótce swoją premierę będzie miał także skryptowy język programowania PowerShell Core. Oba produkty mają wkrótce zrzucić dziwne, mylące i pretensjonalne sufiksy "Core" i stać się pełnoprawnymi następcami swoich dawnych, monolitycznych protoplastów. Przyszłe wersje .NET mają zlikwidować konieczność dostarczania i targetowania specyficznego środowiska uruchomieniowego (zamiast wbudowanego .NET Framework), dzięki zintegrowaniu go z nowymi wersjami Windows.
Również PowerShell dojrzewa i jego ostatnia wersja poglądowa wzbogaciła się o przełącznik -l, umożliwiający wykorzystanie go jako domyślnej powłoki logowania. I choć implementacja owej funkcji jest dość chybotliwa i nieelegancka, stanowi w pewnym sensie przełom. Implikuje bowiem, że PowerShell może być oto z powodzeniem stosowany jako alternatywa dla powłoki bash. Czy tak jest w istocie? Przekonajmy się.
Bajty vs obiekty
Na początku należy zaznaczyć, że tzw. filozofia Uniksa zakłada, że system składa się z wielu małych narzędzi, które "robią tylko jedną rzecz, ale robią ją dobrze". W porównaniu do znacznie mniej rozbudowanych powłok, jak historyczny COMMAND.COM, powłoka Bash oferuje bardzo mało wbudowanych poleceń. Nawet operatory porównań w postaci kwadratowych nawiasów, są implementowane jako program /bin/[, realizujący działanie polecenia test.
Siła współczesnych uniksowych powłok tekstowych tkwi w ich programowalności. Za pomogą skryptów Bash można tworzyć procedury i funkcje wykorzystujące tablice, słowniki pod-powłoki, pętle i różnorakie operatory warunkowe. Interaktywne wykorzystanie Basha, w przeciwieństwie do wykorzystania skryptowego, będzie zatem dość zbliżone do PowerShella: obie powłoki będą wszak wywoływać te same binaria. Dlatego aby poprawnie ocenić przydatność nowego PowerShella jako powłoki uniksowej, należy przyjrzeć się obu rodzajom zastosowań: w pełni interaktywnemu oraz skryptowemu.
Jakoś tu pusto
Sesję PowerShell uruchamia się poleceniem "pwsh". Otrzymujemy w ten sposób sesję oferującą dobrze znanego z Windows PowerShella ale... coś jest nie tak. Nie widać tego przy podstawowych cmdletach, jak Get-ChildItem, ale krótka wędrówka po dostępnych poleceniach i modułach pokazuje, że środowisko uruchomieniowe PowerShell Core na Linuksie jest znacznie, znacznie uboższe, niż wersja 5.1 z "Dziesiątki".
Ponownie podkreślam, że 99 proc. poleceń w Linuksie to wydzielone programy, więc w zasadzie nie ma różnicy, jakiej powłoki są wywoływane. Różnice widać dopiero podczas próby pisania jakiejś algorytmicznej logiki, jak np. pętla foreach. Wtedy wyjdzie na jaw postawowa różnica między Uniksem a Windows: Unix operuje na strumieniach bajtów, a Windows na strukturach i obiektach.
To powłoka jak każda inna
PowerShell 7 oczywiście obsługuje klasyczny linuksowy pipe, ale nie po to nam chyba pwsh na Linuksie, by dalej parsować strumienie bajtów ("...jak zwierzęta"). Chcemy wyzwolić się z cięcia łańcuchów, dzielenia ich na sekcje oddzielane spacjami i rzeźbienia wyrażeń regularnych, podatnych na zmianę wejścia. Jedna aktualizacja narzędzia ifconfig i trzeba zaczynać od nowa. Wszak takie PowerShellowe polecenie Get-NetIPConfiguration grzecznie zwraca obiekt, który zawsze zawiera własność "IPv4Address" typu CimInstance[].
Tylko, że PowerShell 7 nie zawiera polecenia Get-NetIPConfiguration. Nie zawiera też modułu, w którym to polecenie siedzi. W ogóle mało co zawiera. Większość cmdletów administracyjnych, które używam, jest nieobecna. I to nie tylko te naturalnie przeznaczone tylko dla Windows, ale i te o wiele bardziej agnostyczne.
To nie są droidy, których szukacie
Istnieje na przykład Get-Process i zwraca ono obiekty, które można sortować, enumerować, parsować i rozkładać ile wlezie. Tutaj PowerShell 7 zachowuje się tak, jak jego pełnoprawny, starszy wariant 5.1. Ale Get-Service już nie ma, a polecenie systemctl naturalnie w ogóle nie nadaje się do obiektowego użycia w PowerShellu. Output z narzędzi systemd jest bowiem mocno rozbudowany, ale to dalej jest strumień bajtów plus może nieco kombinowania z trybami przewijania w terminalach i semigrafiką. Linuksowe narzędzia po prostu nie nadają się do traktowania jak konstruktory obiektów rozumianych przez .NET. Te rozleniwiające przyzwyczajenia jeszcze nie mapują się na PowerShella, choć zapewne kiedyś kolekcja cmdletów się powiększy. Co gorsza, remoting też działa tylko ledwo-ledwo i wciąż lepiej jest używać SSH...
Po co nam więc ten cały PowerShell na Linuksie? Krytycy Microsoftu i praktykujący wyznawcy kościołów linuksowych zapewne powiedzą, że to sztuka dla sztuki, postrzelony pomysł, marnowanie zasobów i po prostu kolejny bardzo kiepski produkt złowrogiej firmy. Istnieje jednak całkiem niezłe uzasadnienie dla obecności PowerShella na systemach linuksowych. I nie chodzi tu tylko o to, że jest to "pierwszy krok", bez którego nie nastąpią kolejne. Już teraz dostępne są narzędzia wykorzystujące potencjał obiektowej powłoki z Redmond na RHEL-u.
„Język skryptowy specjalnego przeznaczenia”
PowerShell 7 nie ma być bowiem zastępstwem dla basha i nową powłoką mającą konkurować z wieloletnimi rozwiązaniami znanymi z Uniksów. Ma raczej oferować wspólne środowisko uruchomieniowe dla narzędzi do zarządzania systemami, jak Azure DevOps, Microsoft Hyper-V oraz VMWare vSphere. Dzisiejsze narzędzia konsolowe do managementu związanego z owymi produktami są tak rozbudowane, że zamiast tworzyć własną "sub-powłokę", jak serwery SQL, są implementowane jako moduły właśnie do PowerShella.
I jest to strzał w dziesiątkę. Cmdlety przeznaczone do pracy z chmurą Azure oraz maszynami wirtualnymi Hyper-V są niezwykle bogate w funkcje, a jednocześnie wysoce przystępne, łatwe i "odkrywalne" (discoverable). Bardzo często jednak wywołują potrzebę oddelegowania dedykowanej "maszyny zarządzającej" z Windows, zaopatrzonej w PowerShella, a nie każde środowisko pozwala na takie coś bez wyrzeczeń lub frustracji.
Windows opcjonalny
Możliwość osadzenia środowiska uruchomieniowego PowerShell np. na maszynie wirtualnej z Linuksem rozszerza zbiór scenariuszy, w których możliwe jest wykorzystanie narzędzi Microsoftu. Bywają one nierzadko odrzucane z powodu wymagania obecności pełnej, aktywowanej, klienckiej wersji Windows 10. Także VMware już teraz dostarcza swoje moduły PowerCLI w formie działającej w środowisku PowerShell Core na Linuksie. PowerShell, podobnie jak bash, Perl i Python, aspiruje zatem do bycia powłoką działajacą "na wszystkim", bez wygórowanych (i idiotycznych w wielu przypadkach) wymagań.
Świat IT zmienił się na tyle, że nie da się już skutecznie zmuszać całego świata do stosowania wszędzie Windowsów. Klienci prędzej wybiorą po prostu inne rozwiązanie, zamiast głowić się nad meandrami wdrożenia Windows 10 w heterogenicznej chmurze mieszanej i innych kompletnych dziwadłach, z którymi np. taki Python nie miałby najmniejszego problemu.
Jeszcze długa droga
Niewątpliwie takie będzie główne przeznaczenie nowego PowerShella. Najnowsze wydanie nie zostanie już zapewne wzbogacone o żadne nowe funkcje, podobnie jak nadchodzący .NET Core 3.0. Ale już wkrótce możemy się spodziewać coraz ciekawszych rozwiązań w PowerShellu, przybliżających obiektową powłokę do świata uniksowego. Może być interesująco. Zwłaszcza biorąc pod uwagę hate mail wysłany do redakcji po poprzednim artykule (niektóre wypracowania krytykujące użycie konstrukcji for i in ls
były dłuższe od samego tekstu!). 😉