Powłoka jest interpreterem poleceń dla systemu operacyjnego. Bash jest moją ulubioną powłoką, ale każda powłoka linuksowa interpretuje polecenia wpisywane przez użytkownika lub administratora w formę, którą system operacyjny może wykorzystać. Gdy wyniki zwracane są do programu powłoki, wysyła je on do STDOUT, który domyślnie wyświetla je w terminalu. Wszystkie powłoki, jakie znam, są także językami programowania.

Funkcje takie jak uzupełnianie tabulatorów, przywoływanie i edycja wiersza poleceń, i skróty takie jak aliasy, wszystkie przyczyniają się do jej wartości jako potężnej powłoki. Jego domyślny tryb edycji wiersza poleceń używa Emacsa, ale jedną z moich ulubionych cech Basha jest to, że mogę go zmienić na tryb Vi, by używać poleceń edycji, które są już częścią mojej pamięci mięśniowej.

Jednakże, jeśli myślisz o Bashu wyłącznie jako o powłoce, brakuje ci wiele z jego prawdziwej mocy. Podczas badań nad moim trzytomowym kursem samodzielnej nauki Linuksa (na którym oparta jest ta seria artykułów), dowiedziałem się o Bashu rzeczy, których nie wiedziałem przez ponad 20 lat pracy z Linuksem. Niektóre z tych nowych fragmentów wiedzy odnoszą się do jego zastosowania jako języka programowania. Bash jest potężnym językiem programowania, doskonale zaprojektowanym do używania w wierszu poleceń i w skryptach powłoki.

Ta trzyczęściowa seria bada użycie Basha jako języka programowania interfejsu wiersza poleceń (CLI). W pierwszym artykule omówiono proste programowanie w wierszu poleceń z użyciem Basha, zmiennych i operatorów sterujących. Pozostałe artykuły omawiają typy plików Bash; operatory łańcuchowe, numeryczne i różne operatory logiczne, które zapewniają logikę kontroli przepływu wykonania; różne typy rozszerzeń powłoki; oraz pętle for, while i until, które umożliwiają wykonywanie powtarzalnych operacji. Przyjrzą się również niektórym poleceniom, które upraszczają i wspierają korzystanie z tych narzędzi.

Powłoka

Powłoka jest interpreterem poleceń dla systemu operacyjnego. Bash jest moją ulubioną powłoką, ale każda powłoka Linuksa interpretuje polecenia wpisywane przez użytkownika lub administratora do postaci, którą system operacyjny może wykorzystać. Gdy wyniki zwracane są do programu powłoki, wyświetla je on w terminalu. Wszystkie powłoki, które znam, są również językami programowania.

Bash oznacza Bourne Again Shell, ponieważ powłoka Bash oparta jest na starszej powłoce Bourne’a, napisanej przez Stevena Bourne’a w 1977 roku. Dostępnych jest wiele innych powłok, ale są to cztery, z którymi stykam się najczęściej:

  • csh: Powłoka C dla programistów, którzy lubią składnię języka C
  • ksh: Powłoka Korn, napisana przez Davida Korna i popularna wśród użytkowników Uniksa
  • tcsh: Wersja csh z większą ilością funkcji ułatwiających użytkowanie
  • zsh: Powłoka Z, która łączy w sobie wiele cech innych popularnych powłok

Wszystkie powłoki mają wbudowane polecenia, które uzupełniają lub zastępują te dostarczane przez podstawowe narzędzia. Otwórz stronę man powłoki i znajdź sekcję „BUILT-INS”, by zobaczyć polecenia, jakie udostępnia.

Każda powłoka ma swoją własną osobowość i składnię. Niektóre będą działać dla ciebie lepiej niż inne. Używałem powłoki C, powłoki Korn i powłoki Z. Nadal bardziej podoba mi się powłoka Bash niż którakolwiek z nich. Użyj tej, która działa dla Ciebie najlepiej, choć może to wymagać wypróbowania niektórych z pozostałych. Na szczęście, dość łatwo jest zmienić powłokę.

Wszystkie te powłoki są językami programowania, jak również interpreterami poleceń. Oto krótka wycieczka po niektórych konstrukcjach programistycznych i narzędziach, które są integralną częścią Basha.

Bash jako język programowania

Większość administratorów używa Basha do wydawania poleceń, które są zwykle dość proste i nieskomplikowane. Ale Bash może wykraczać poza wydawanie pojedynczych poleceń, a wielu administratorów tworzy proste programy wiersza poleceń do wykonywania serii zadań. Programy te są powszechnymi narzędziami, które mogą oszczędzić czas i wysiłek.

Moim celem podczas pisania programów CLI jest oszczędzanie czasu i wysiłku (tzn. bycie leniwym sysadminem). Programy CLI wspierają to przez wypisanie kilku poleceń w określonej sekwencji, które wykonują się jedno po drugim, więc nie musisz obserwować postępu jednego polecenia i wpisywać następnego, gdy pierwsze się skończy. Możesz iść robić inne rzeczy i nie musisz ciągle monitorować postępu każdego polecenia.

Co to jest „program”?

Wolny słownik on-line informatyki (FOLDOC) definiuje program jako: „Instrukcje wykonywane przez komputer, w przeciwieństwie do fizycznego urządzenia, na którym są uruchamiane”. Princeton University’s WordNet definiuje program jako: „…ciąg instrukcji, które komputer może zinterpretować i wykonać…”. Wikipedia ma również dobry wpis o programach komputerowych.

W związku z tym program może składać się z jednej lub więcej instrukcji, które wykonują określone, powiązane zadanie. Instrukcja programu komputerowego jest również nazywana instrukcją programu. Dla administratorów, program jest zwykle sekwencją poleceń powłoki. Wszystkie powłoki dostępne dla Linuksa, przynajmniej te, które znam, mają przynajmniej podstawową formę możliwości programowania, a Bash, domyślna powłoka większości dystrybucji Linuksa, nie jest wyjątkiem.

Podczas gdy ta seria używa Basha (ponieważ jest on tak wszechobecny), jeśli używasz innej powłoki, ogólne koncepcje programowania będą takie same, choć konstrukcje i składnia mogą się nieco różnić. Niektóre powłoki mogą obsługiwać pewne funkcje, których inne nie obsługują, ale wszystkie zapewniają pewne możliwości programistyczne. Programy powłoki mogą być przechowywane w pliku do wielokrotnego użytku, lub mogą być tworzone w wierszu poleceń w razie potrzeby.

Proste programy CLI

Najprostsze programy wiersza poleceń to jedno lub dwa kolejne wyrażenia programu, które mogą być powiązane lub nie, które są wprowadzane w wierszu poleceń przed naciśnięciem klawisza Enter. Druga instrukcja w programie, jeśli istnieje, może być zależna od działań pierwszej, ale nie musi być.

Jest też jedna odrobina składniowej interpunkcji, która musi być jasno określona. Podczas wprowadzania pojedynczego polecenia w wierszu poleceń, naciśnięcie klawisza Enter kończy polecenie z niejawnym średnikiem (;). Gdy używany jest w programie powłoki CLI wprowadzonym jako pojedynczy wiersz w wierszu poleceń, średnik musi być użyty do zakończenia każdego polecenia i oddzielenia go od następnego. Ostatnia instrukcja w programie powłoki CLI może używać jawnego lub ukrytego średnika.

Nieco podstawowej składni

Następujące przykłady wyjaśnią tę składnię. Ten program składa się z pojedynczego polecenia z jawnym terminatorem:

$ echo "Hello world." ;
Hello world.

To może nie wydawać się zbyt wielkim programem, ale jest to pierwszy program, z którym stykam się w każdym nowym języku programowania, którego się uczę. Składnia może być nieco inna dla każdego języka, ale wynik jest taki sam.

Rozwińmy trochę ten trywialny, ale wszechobecny program. Twoje wyniki będą się różnić od moich, ponieważ przeprowadziłem inne eksperymenty, podczas gdy ty możesz mieć tylko domyślne katalogi i pliki, które są tworzone w katalogu domowym konta przy pierwszym zalogowaniu się na konto przez pulpit GUI.

$ echo "My home directory." ; ls ;
My home directory.
chapter25 TestFile1.Linux dmesg2.txt Downloads newfile.txt softlink1 testdir6
chapter26 TestFile1.mac dmesg3.txt file005 Pictures Templates testdir
TestFile1 Desktop dmesg.txt link3 Public testdir Videos
TestFile1.dos dmesg1.txt Documents Music random.txt testdir1

To ma trochę więcej sensu. Wyniki są powiązane, ale poszczególne instrukcje programu są od siebie niezależne. Zauważ, że lubię stawiać spacje przed i po średniku, ponieważ to sprawia, że kod jest nieco łatwiejszy do odczytania. Wypróbuj ten mały program CLI ponownie bez wyraźnego średnika na końcu:

$ echo "My home directory." ; ls 

Nie ma żadnej różnicy w wynikach.

Coś o zmiennych

Jak wszystkie języki programowania, powłoka Bash może radzić sobie ze zmiennymi. Zmienna jest nazwą symboliczną, która odnosi się do określonej lokalizacji w pamięci, zawierającej jakąś wartość. Wartość zmiennej jest zmienna, tzn. jest zmienna.

Bash nie typuje zmiennych jak C i języki pokrewne, definiując je jako liczby całkowite, zmiennoprzecinkowe lub łańcuchowe. W Bashu wszystkie zmienne są łańcuchami. Łańcuch będący liczbą całkowitą może być użyty w arytmetyce liczb całkowitych, która jest jedynym rodzajem matematyki, do jakiej zdolny jest Bash. Jeśli wymagana jest bardziej złożona matematyka, w programach i skryptach CLI można użyć polecenia bc.

Zmienne mają przypisane wartości i mogą być używane do odwoływania się do tych wartości w programach i skryptach CLI. Wartość zmiennej ustawia się, używając jej nazwy, ale nie poprzedzając jej znakiem $. Przypisanie VAR=10 ustawia wartość zmiennej VAR na 10. Aby wypisać wartość zmiennej, można użyć polecenia echo $VAR. Zaczynaj od zmiennych tekstowych (tj. nienumerycznych).

Zmienne Bash stają się częścią środowiska powłoki, dopóki nie zostaną wyłączone.

Sprawdź wartość początkową zmiennej, która nie została przypisana; powinna być zerowa. Następnie przypisz wartość zmiennej i wypisz ją, by zweryfikować jej wartość. Możesz to wszystko zrobić w jednym programie CLI:

$ echo $MyVar ; MyVar="Hello World" ; echo $MyVar ;
Hello World
$

Uwaga: Składnia przypisywania zmiennych jest bardzo ścisła. Po obu stronach znaku równości (=) w instrukcji przypisania nie może być spacji.

Pusta linia wskazuje, że początkowa wartość MyVar jest zerowa. Zmiana i ustawianie wartości zmiennej odbywa się w ten sam sposób. Ten przykład pokazuje zarówno oryginalną, jak i nową wartość.

Jak wspomniano, Bash może wykonywać obliczenia arytmetyczne na liczbach całkowitych, co jest przydatne do obliczania odniesienia do położenia elementu w tablicy lub wykonywania prostych problemów matematycznych. Nie nadaje się on do obliczeń naukowych ani do niczego, co wymaga liczb dziesiętnych, takich jak obliczenia finansowe. Istnieją znacznie lepsze narzędzia do tego typu obliczeń.

Oto proste obliczenie:

$ Var1="7" ; Var2="9" ; echo "Result = $((Var1*Var2))"
Result = 63

Co się stanie, gdy wykonasz operację matematyczną, której wynikiem będzie liczba zmiennoprzecinkowa?

Wynikiem jest najbliższa liczba całkowita. Zauważ, że obliczenia zostały wykonane jako część instrukcji echo. Matematyka jest wykonywana przed zamykającym poleceniem echo, ze względu na kolejność pierwszeństwa w Bashu. Po szczegóły zajrzyj na stronę podręcznika Bash i wyszukaj „precedence.”

Operatory sterujące

Operatory sterujące powłoki są jednym z operatorów składniowych umożliwiających łatwe tworzenie ciekawych programów wiersza poleceń. Najprostszą formą programu CLI jest po prostu połączenie kilku poleceń w sekwencję w wierszu poleceń:

command1 ; command2 ; command3 ; command4 ; . . . ; etc. ;

Te polecenia działają bez problemu tak długo, jak nie wystąpią żadne błędy. Ale co się stanie, gdy pojawi się błąd? Można przewidzieć i dopuścić błędy używając wbudowanych operatorów kontrolnych && i || Bash. Te dwa operatory sterujące zapewniają pewną kontrolę przepływu i umożliwiają zmianę sekwencji wykonywania kodu. Średnik jest również uważany za operator kontroli Bash, podobnie jak znak nowej linii.

Operator && mówi po prostu: „jeśli polecenie1 powiedzie się, to uruchom polecenie2. Jeśli polecenie1 nie powiedzie się z jakiegokolwiek powodu, to polecenie2 jest pomijane”. Składnia ta wygląda następująco:

command1 && command2

A teraz spójrz na kilka poleceń, które utworzą nowy katalog i – jeśli się powiedzie – uczynią go obecnym katalogiem roboczym (PWD). Upewnij się, że twoim katalogiem domowym (~) jest PWD. Spróbuj tego najpierw w /root, katalogu, do którego nie masz dostępu:

Błąd został wyemitowany przez polecenie mkdir. Nie otrzymałeś błędu wskazującego, że plik nie mógł zostać utworzony, ponieważ utworzenie katalogu nie powiodło się. Operator sterowania && wyczuł niezerowy kod powrotu, więc polecenie touch zostało pominięte. Użycie operatora sterowania && zapobiega uruchomieniu polecenia touch, ponieważ wystąpił błąd podczas tworzenia katalogu. Tego typu kontrola przepływu programu w wierszu poleceń może zapobiec kumulowaniu się błędów i wprowadzaniu prawdziwego bałaganu. Ale nadszedł czas na nieco bardziej skomplikowane czynności.

Operator sterujący || pozwala dodać kolejną instrukcję programu, która zostanie wykonana, gdy początkowa instrukcja programu zwróci kod większy od zera. Podstawowa składnia wygląda tak:

command1 || command2 

Składnia ta brzmi: „Jeśli polecenie1 nie powiedzie się, wykonaj polecenie2”. Sugeruje to, że jeśli polecenie1 się powiedzie, polecenie2 jest pomijane. Spróbuj tego, próbując utworzyć nowy katalog:

To jest dokładnie to, czego można by się spodziewać. Ponieważ nowy katalog nie mógł zostać utworzony, pierwsze polecenie zakończyło się niepowodzeniem, co spowodowało wykonanie drugiego polecenia.

Połączenie tych dwóch operatorów zapewnia najlepsze z obu. Składnia operatora sterowania wykorzystująca pewne sterowanie przepływem przyjmuje taką ogólną postać, gdy używane są operatory sterowania && i ||:

preceding commands ; command1 && command2 || command3 ; following commands

Składnię tę można podać tak: „Jeśli polecenie1 zakończy pracę z kodem powrotu 0, to wykonaj polecenie2, w przeciwnym razie wykonaj polecenie3”. Spróbuj tego:

Teraz spróbuj ostatniego polecenia ponownie, używając swojego katalogu domowego zamiast katalogu /root. Będziesz miał uprawnienia do utworzenia tego katalogu:

$ Dir=~/testdir ; mkdir $Dir && cd $Dir || echo "$Dir was not created."
$

Składnia operatora sterowania, jak polecenie1 &&polecenie2, działa, ponieważ każde polecenie wysyła do powłoki kod powrotu (RC), który wskazuje, czy zakończyło się ono pomyślnie, czy też wystąpił jakiś rodzaj niepowodzenia podczas wykonywania. Umownie, RC równy zero (0) oznacza sukces, a każda liczba dodatnia wskazuje na jakiś rodzaj niepowodzenia. Niektóre z używanych przez administratorów narzędzi zwracają jedynkę (1), by wskazać niepowodzenie, ale wiele z nich używa innych kodów, by wskazać rodzaj niepowodzenia, które wystąpiło.

Zmienna powłoki Bash $? zawiera RC z ostatniego polecenia. Ten RC może być bardzo łatwo sprawdzony przez skrypt, następne polecenie na liście poleceń, lub nawet bezpośrednio przez administratora. Zacznij od uruchomienia prostej komendy i natychmiastowego sprawdzenia RC. RC zawsze będzie dla ostatniej komendy, która została uruchomiona zanim na nią spojrzałeś.

RCN, w tym przypadku, wynosi zero, co oznacza, że komenda zakończyła się powodzeniem. Teraz spróbuj wykonać to samo polecenie w katalogu domowym root’a, katalogu, do którego nie masz uprawnień:

W tym przypadku RC wynosi dwa; oznacza to, że odmówiono pozwolenia użytkownikowi niebędącemu root’em na dostęp do katalogu, do którego nie ma on dostępu. Operatory kontroli używają tych RC, aby umożliwić zmianę kolejności wykonywania programu.

Podsumowanie

Ten artykuł przyglądał się Bashowi jako językowi programowania i badał jego podstawową składnię, jak również kilka podstawowych narzędzi. Pokazano jak drukować dane do STDOUT oraz jak używać zmiennych i operatorów sterujących. W następnym artykule z tej serii przyjrzymy się niektórym z wielu operatorów logicznych Basha, które kontrolują przepływ wykonywania instrukcji.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.