Rozdział 13.
Podbój powłoki BASH
Rozdział ten opisuje potęgę powłoki BASH zdecydowanie bardziej szczegółowo, niż to miało miejsce w
rozdziale 4. Przedstawione zostaną zmienne, skrypty i aliasy powłoki przygotowujące do zaawansowanej pracy
w systemie Linux.
Powłoka Linuksa
Poznałeś już wcześniej interpreter poleceń systemu Linux, czyli tzw. powłokę. Podobnie jak okno wiersza
poleceń trybu MS-DOS, powłoka pozwala wydawać polecenia, które są przez nią interpretowane i wykonywane.
Poprzez powłokę właśnie kontrolujesz system Linux i zarządzasz nim.
Różnorodność powłok
Powłoka systemu MS-DOS była przez cały czas w miarę niezmienna, na przykład między 3. wersją MS-DOS a
wersją 7. różnic (zmian) było niewiele. Inaczej jest w przypadku powłoki systemu Unix, która przeszła wiele
zmian oraz miała trochę inną drogę ewolucji niż konkurentka z MS-DOS. Obecnie możemy znalezć wiele wersji
i odmian powłoki systemu Unix. Odmiany powłoki mają ze sobą dużo wspólnego, ale każda z nich ma na pewno
innego autora i historię powstania oraz sposób, w jaki współpracuje z nią użytkownik.
Linux posiada większość najpopularniejszych powłok systemu Unix; są one przedstawione w tabeli 13.1.
Najczęściej używaną z nich wszystkich jest właśnie powłoka BASH (Bourne Again Shell) opracowana na
podstawie oryginalnej powłoki Unix Bourne. Jest ona w dużym stopniu kompatybilna ze standardem POSIX,
który określa składnię i działanie standardowych powłok Uniksa i który został szeroko rozpowszechniony. Ze
względu na popularność tego standardu oraz na oczywiste korzyści płynące z pracy z powłokami, które są
zgodne z wieloma platformami komputerowymi, rozdział ten skupia się głównie na powłoce BASH. Większość
dystrybucji systemu Linux jest tak skonfigurowana, aby automatycznie uruchamiać tę powłokę zaraz po
zalogowaniu. Po więcej informacji na temat innych powłok systemu Linux zajrzyj na odpowiednie strony
podręcznika systemowego man.
Tabela 13.1. Powszechnie używane powłoki systemu Linux
Nazwa powłoki Nazwa programu Opis
Powłoka ASH /bin/ash Przypomina powłokę używaną przez System V firmy AT&T.
/bin/bsh
Powłoka BASH /bin/bash Standardowa powłoka Linuksa, powstała na bazie oryginalnej
powłoki Uniksa Bourne. Według stron man dotyczących
/bin/bash2
tej powłoki BASH jest kompatybilna ze standardem POSIX.
Powłoka C /bin/csh Druga pod względem popularności powłoka Uniksa.
Zaprojektowana do interaktywnego użytkowania, posiada
/bin/tcsh
wiele funkcji i właściwości. Jej składnia przypomina język
programowania C.
Powłoka Korna /bin/ksh Połączenie powłoki C (część funkcji) i oryginalnej powłoki
Bourne a. Trzecia w rankingu.
Powłoka Z /bin/zsh Powłoka oparta na powłoce Korna, posiada wiele
wbudowanych właściwości.
Dlaczego warto uczyć się poleceń powłoki?
Jeśli jesteś przyzwyczajony do używania graficznego interfejsu użytkownika, możesz zadawać sobie pytanie,
czy warto jest się uczyć powłoki Linuksa. Wielu bowiem początkujących użytkowników tego systemu twierdzi,
że praca z powłoką jest kłopotliwa, część z nich instaluje graficzny interfejs użytkownika i unika powłoki jak
ognia.
Prawdą jest, że interfejs tekstowy jest starszą formą interakcji użytkownika z komputerem, ale tak się składa, że
obecnie interfejs graficzny jest bardziej prymitywny niż znakowy. A to dlatego, że nie został jeszcze w pełni
rozwinięty. Jest on co prawda łatwiejszy w użyciu, częściej stosowany, ale nie jest tak wyrafinowany i wydajny
jak powłoka. Używanie graficznego interfejsu użytkownika przypomina czasami język migowy Indian
amerykańskich. Jeśli wiadomość, którą chcesz komuś przekazać, jest krótka i prosta jak np. przybywam w
pokoju , możesz ją wypowiedzieć przy użyciu kilku gestów. Natomiast jeśli chciałbyś komuś wytłumaczyć
różnice pomiędzy interfejsem graficznym a znakowym, mógłbyś mieć wiele problemów.
Każdy narodowy język migowy, używany głównie przez ludzi niesłyszących, jest bogatszy niż indiański język
migowy. Niestety programiści jeszcze nie potrafią stworzyć interfejsu graficznego o tak złożonej strukturze.
Projektant takiego interfejsu musi przewidywać wszystkie sposoby, jakimi użytkownik będzie komunikował się
z systemem, i dostarczyć odpowiednich metod (tylko za pomocą wskazywania i klikania myszką!), aby program
mógł prawidłowo reagować na żądania użytkownika. W związku z tym użytkownik jest właściwie zmuszany do
wykonywania ściśle określonych operacji i dlatego nie może zaadaptować programu interfejsu graficznego do
wykonywania nieprzewidzianych zadań i odpowiadania na nieokreślone okoliczności. Ze względu na dużą
odpowiedzialność za utrzymanie systemu i bezpieczeństwo danych, gdzie wciąż trzeba zmagać się z
nieprzewidywalnymi zdarzeniami i problemami, większość administratorów wykonuje swoje zadania przy
użyciu powłoki, a nie interfejsu graficznego.
Powłoka jest odzwierciedleniem filozofii systemu Unix, który dostarcza wielu małych i prostych narzędzi
(programów), z których każde wykonujące jedno zadanie. Kiedy zachodzi potrzeba wykonania złożonej
operacji, narzędzia współpracują ze sobą, wykonując działania jedno po drugim. Wiele narzędzi systemu Unix
manipuluje tekstem, a od czasu, kiedy Unix przechowuje dane w formie tekstu, a nie w formie binarnej,
narzędzia te idealnie zaczęły się nadawać do sterowania pracą samego systemu. Taką właściwość daje powłoka
łączenie narzędzi do wspólnego wykonywania zadań systemowych, co stanowi o sile i wydajności wszystkich
systemów uniksowych. Dodatkowo powłoka jest rozszerzalna możesz tworzyć skrypty powłoki, które
pozwalają przechowywać szereg poleceń do pózniejszego wykonania, oszczędza to czas, który zmarnowałbyś
wpisując te polecenia za każdym razem, gdy zamierzasz wykonać konkretne zadanie.
Odwrotną filozofię można zaobserwować w systemie Microsoft Windows, który obsługuje monolityczne
programy, zawierające menu, podmenu i okna dialogowe. Takie programy nie mają jak ze sobą współpracować,
więc raczej niemożliwe jest wykonywanie złożonych zadań. Są łatwe w użyciu, ale tylko wtedy, gdy musisz
wykonać jedno zadanie, do którego zostały zaprojektowane, natomiast kiedy spróbujesz wykonać operację inną
drogą niż zaprogramowana, napotkasz same trudności.
Oczywiście nie wszyscy zgadzają się z tą opinią. Grupy dyskusyjne są przepełnione wiadomościami mówiącymi
o zaletach środowiska graficznego. Niektórzy z użytkowników takich grup postrzegają systemy Unix jako
zabytkowe zabawki. Nawet jeśli mają rację, to jedynie ucząc się poleceń i funkcji powłoki, przekonasz się sam,
do czego tak naprawdę przydatny jest obecnie taki system.
Zdanie autora jest jednoznaczne kiedy wykonujesz proste, pojedyncze zadanie, możesz używać interfejsu
graficznego, który umili ci pracę, ale podczas wykonywania skomplikowanego zadania administracyjnego,
wymagającego od użytkownika wyobrazni i myślenia, stanowczo zalecam używanie powłoki (przekonaj się
sam!). Rozwiązania stworzone za pomocą funkcji i poleceń powłoki mogą być zapisane do pliku i wykorzystane
ponownie w przyszłości, niekoniecznie do wykonania tego samego zadania. Co ważniejsze, podczas
rozwiązywania powiązanych problemów, skrypty powłoki mogą zostać użyte do przypomnienia dawno
zapomnianych szczegółów.
Używanie powłoki
Powłoka systemu Linux została już przedstawiona w rozdziale 4. Jednakże wiele bardzo ważnych szczegółów
zostało w nim pominiętych ze względu na jej funkcje; rozdział umożliwiał szybkie uruchomienie systemu i
zapoznanie z podstawowymi operacjami. Rozszerzymy jednak zagadnienia dotyczące powłoki i opiszemy je w
szczegółowy sposób.
Wprowadzanie poleceń
Wpisując nazwy programów lub skryptów w wierszu poleceń, masz dostęp do miniedytora, który przypomina
program DOSKEY znany z systemu MS-DOS. Tabela 13.2 podsumowuje niektóre użyteczne skróty klawiszowe
interpretowane przez powłokę jako polecenia. Skróty te umożliwiają dostęp do ostatnio wydawanych poleceń
zapisanych w historii. Aby ponownie wydać polecenie, możesz kilkakrotnie nacisnąć klawisz kursora w górę i
po znalezieniu żądanego nacisnąć Enter.
Tabela 13.2. Użyteczne skróty klawiatury
Klawisz Funkcja
Up Przesuwa się o jedno polecenie wstecz na liście historii.
Down Przesuwa się o jedno polecenie do przodu na liście historii.
Left Przesuwa kursor o jeden znak do tyłu.
Right Przesuwa kursor o jeden znak do przodu.
Esc f Przesuwa kursor o jedno słowo do przodu.
Esc b Przesuwa kursor o jedno słowo do tyłu.
Ctrl+A Przenosi kursor na początek wiersza.
Ctrl+E Przenosi kursor na koniec wiersza.
Ctrl+D Kasuje znak nad kursorem.
Backspace Kasuje pierwszy znak przed kursorem.
Esc d Kasuje cały wyraz.
Ctrl+U Kasuje od początku wiersza.
Esc k Usuwa od końca wiersza.
Ctrl+Y Odzyskuje ostatnio usunięty element (znak, wyraz).
Esc . Wstawia ostatni wyraz poprzedniego polecenia.
Ctrl+L Czyści ekran, ustawiając aktualny wiersz na samej górze ekranu.
Tab Dopełnia słowa lub wyrazy, interpretując je jako nazwę pliku, nazwę użytkownika, nazwę
zmiennej, nazwę hosta lub polecenia zależnie od kontekstu.
Esc ? Wyświetla listę możliwych dopełnień.
Jednym z bardziej użytecznych poleceń klawiatury jest Tab, który również może być stosowany do wydawania
poleceń. Jeśli na przykład wpiszesz pewną część nazwy pliku i wciśniesz klawisz Tab, powłoka postara się
zlokalizować plik, którego nazwa pokrywa się z wprowadzonymi znakami. Jeśli dokładnie jeden plik zostanie
znaleziony i w dodatku dokładnie jego się spodziewałeś, powłoka dopełni nazwę, a ty naciśnij Enter, aby
wykonać polecenie. Ta właściwość zwana jest dopełnieniem nazw plików lub dopełnieniem poleceń i znacznie
ułatwia używanie powłoki.
Oprócz powyższych skrótów klawiaturowych powłoka interpretuje jeszcze kilka innych sekwencji klawiszy,
które kontrolują operacje wykonywanych aktualnie programów. Tabela 13.3 opisuje sekwencje. Na przykład
jednoczesne wciśnięcie klawiszy Ctrl+C powoduje przerwanie działania programu i jego zakończenie.
Polecenie to jest pomocne, gdy samo wykonywanie programu zajmuje dużo czasu, a istnieją inne sposoby na
jego szybsze wykonanie.
Tabela 13.3. Klawisze kontrolne
Sekwencja klawiszy Funkcja
Ctrl+C Wysyła do aktualnie wykonywanego polecenia sygnał przerwania, co generalnie
powoduje zakończenie działania programu.
Ctrl+D Wysyła do aktualnie wykonywanego polecenia sygnał końca pliku. Blokuje wejście
konsoli.
Ctrl+Z Zatrzymuje wykonywanie aktualnie aktywnego zadania.
Istnieje kilka innych specjalnych klawiszy kontrolujących działanie powłoki (patrz tabela 13.4). Znaki # i ; są
często używanymi znakami w skryptach powłoki, o których przeczytasz jeszcze w tym rozdziale. Znak & jest
głównie używany do uruchamiania poleceń w tle.
Tabela 13.4. Inne specjalne znaki powłoki
Znak Funkcja
#
Zaznacza polecenie jako komentarz, przez co interpreter powłoki ją ignoruje.
;
Oddziela polecenia i pozwala wpisywać kilka w jednym wierszu.
&
Znak umieszczony na końcu polecenia powoduje uruchomienie go w tle, tak że po naciśnięciu
klawisza Enter pojawia się natychmiast znak zachęty powłoki.
Polecenia i argumenty
Jak już zapewne wiesz, generalna składnia polecenia powłoki wygląda następująco:
polecenie opcje argumenty
W powyższym przykładzie polecenie określa operację, którą ma wykonać powłoka; opcje i argumenty
wpływają na przebieg działania i zakres operacji. Czasami polecenie oznacza plik programu do
uruchomienia. wtedy polecenie nazywane jest poleceniem zewnętrznym. Linux przechowuje te pliki w
katalogach /bin, /usr/bin lub /usr/local/bin. Polecenia administracyjne są zazwyczaj przechowywane w katalogu
/sbin lub /usr/sbin. Kiedy polecenie określa plik programu, powłoka przekazuje wszystkie podane argumenty i
opcje do programu, który sprawdza je i interpretuje, następnie wprowadza wraz z poleceniem.
Jednakże niektóre polecenia nie są plikami programów, są za to wbudowane w strukturę powłoki i przez nią
tylko interpretowane. Sposób, w jaki powłoki obsługują wbudowane polecenia, jest jedną z cech, które różnią
powłoki od siebie. Jeszcze w tym rozdziale znajdziesz kilka poleceń wbudowanych w powłokę BASH.
Uogólnianie nazewnictwa plików (Filename globbing)
Zanim powłoka przekaże argumenty i opcje do zewnętrznego programu lub zinterpretuje wbudowane polecenie,
sprawdza wiersz poleceń, poszukując znaków specjalnych i wykonuje operację zwaną uogólnianiem
nazewnictwa plików (filename globbing). Jest to operacja przypominająca przetwarzanie symboli
wieloznacznych (wildcards) w systemie MS-DOS, ale o wiele bardziej złożona. Tabela 13.5 opisuje znaki
specjalne używane przy rozwijaniu nazewnictwa plików, zwane także metaznakami plikowymi.
Meta znak Znaczenie
*
Dopasowuje łańcuch dowolnych znaków (nawet brak znaku jest dopuszczalny).
?
Dopasowuje dokładnie jeden znak.
[abc ...]
Dopasowuje każdy podany znak.
[a-z]
Dopasowuje każdy znak z podanego zakresu.
[!abc ...]
Dopasowuje każdy znak inny niż podane.
[!a-z]
Dopasowuje każdy znak nie podany w zakresie.
~
Oznacza katalog macierzysty aktualnego użytkownika.
~userid
Określa katalog macierzysty podanego użytkownika.
~+
Obecny katalog roboczy.
~-
Poprzedni katalog roboczy.
W operacji uogólniania nazewnictwa plików (zwanej też rozwijaniem nazewnictwa), podobnie jak przy
przetwarzaniu symboli wieloznacznych (wildcards) w systemie MS-DOS, powłoka przystępuje do zamiany
metaznaków pojawiających się jako argumenty polecenia w taki sposób, że argumenty te określają teraz nazwy
plików. Rozwijanie nazewnictwa plików ułatwia określanie nazw plików oraz grup plików.
Na przykład załóżmy, że aktualny katalog roboczy zawiera cztery pliki o nazwach: plik1, plik2, plik3 i plik04.
Chcemy poznać rozmiar każdego z nich. Pomoże nam w tym następujące polecenie:
ls l plik1 plik2 plik3 plik04
Jednakże poniższe polecenie wyświetli nam te same informacje, a w dodatku jest krótsze:
ls l plik*
Jak pokazuje tabela 13.5, metaznak * odpowiada wszystkim znakom i łańcuchom znaków. Kolejny przykład:
ls l plik?
Metaznak ? odpowiada tylko pojedynczemu znakowi (a nie łańcuchowi znaków). Wobec tego nie zobaczysz
informacji na temat plik04.
Podobnie polecenie:
ls l plik[2-3]
wyświetli tylko informacje o plikach: plik2 i plik3, ponieważ tylko ich nazwy mieszczą się w zakresie
określonych znaków [2-3].
Następną ważną cechą jest możliwość podania kilku metaznaków dla jednego argumentu. Rozważmy taki
przykład:
ls l plik??
Polecenie to wyświetli informacje dotyczące plik04, ponieważ każdy metaznak odpowiada dokładnie jednemu
brakującemu znakowi występującemu w nazwie pliku.
Większość poleceń pozwala podać kilka argumentów. Jeśli żaden plik nie pasuje do podanego argumentu,
polecenie ignoruje taki argument. Oto kolejne polecenie wyświetlające wszystkie cztery pliki:
ls l file0* file[1-3]
Uwaga
Przypuśćmy, że polecenie posiada kilka argumentów, z których każdy zawiera kilka metaznaków. Jeśli żaden
z argumentów nie będzie pasował do żadnego pliku, powłoka przekaże argumenty z niezmienionymi
metaznakami do programu. Program spodziewający się ważnej nazwy pliku zwróci komunikat o
niespodziewanym błędzie.
Inny metaznak pozwala w prosty sposób odwołać się do katalogu macierzystego. Na przykład wydając
następujące polecenie:
ls ~
spowodujesz wyświetlenie zawartości plików we własnym katalogu macierzystym.
Metaznaki nie istnieją po to, by zaoszczędzić czasu na wpisywaniu nazw plików. Pozwalają natomiast pisać
skrypty, które selektywnie przetwarzają pliki poprzez ich nazwy. Jeszcze w tym rozdziale zobaczysz, jak to
działa.
Aliasy
Aliasy powłoki ułatwiają używanie poleceń poprzez umożliwianie tworzenia skróconych nazw dla poleceń wraz
z ich argumentami. Aby utworzyć alias dla dowolnego polecenia, skorzystaj z podanego przykładu:
alias nazwa='polecenie'
gdzie polecenie oznacza polecenie, dla którego chcesz utworzyć alias, a nazwa określa nazwę aliasu.
Przypuśćmy, że zamiast linuksowego polecenia ls wpisujesz wciąż z przyzwyczajenia polecenie dir znane z
systemu MS-DOS. Możesz utworzyć alias dla polecenia ls o nazwie dir w następujący sposób:
alias dir='ls l'
Teraz gdy utworzyłeś już alias dla polecenia ls l, nawet gdy się pomylisz i wpiszesz polecenie dir, to i tak
zostanie wyświetlona zawartość aktualnego katalogu roboczego, a nie komunikat command not found (nie
znaleziono polecenia). Również dla innych poleceń możesz tworzyć aliasy.
Domyślna konfiguracja systemu Linux posiada zapewne kilka już zdefiniowanych aliasów. Aby je zobaczyć,
wydaj polecenie:
alias
Jeśli jesteś zalogowany na koncie użytkownika root, zobaczysz prawdopodobnie coś takiego:
alias cp='cp i'
alias dir='ls l'
alias ls='ls --color'
alias mv='mv i'
alias rm='rm i'
Zauważ, że niektóre polecenia posiadają aliasy samych siebie. Na przykład rm i posiada alias rm. Efekt jest
taki, że polecenie rm używa opcji i niezależnie od tego, czy wpiszesz ją w wierszu poleceń czy też nie; a
określa on, czy powłoka ma prosić o potwierdzenie wykonania polecenia rm (usunięcia plików). Zapobiega to
przypadkowemu usunięciu plików, które mogłoby się okazać fatalne w skutkach, zwłaszcza jeśli jesteś
zalogowany jako root i usunąłeś właśnie ważne pliki systemowe. Jeśli nie chcesz być pytany o potwierdzenie
usuwania plików, wydaj polecenie:
rm f pliki
gdzie pliki to nazwy plików do usunięcia. Opcja f posiada odwrotne do opcji i znaczenie: wymusza
usuwanie bez potwierdzania. Ponieważ polecenie posiada alias, tak naprawdę wygląda następująco:
rm i f pliki
Opcja f jest tutaj nadrzędna, tzn. tylko ona jest brana pod uwagę, gdyż występuje dalej w wierszu polecenia.
Jeśli chcesz usunąć alias, wydaj polecenie unalias:
unalias alias
gdzie zmienna alias określa alias, który chcesz usunąć. Takie skróty poleceń są ważne tylko podczas trwania
bieżącej sesji, więc tak naprawdę nie musisz ich wcale usuwać. Jeżeli jednak chciałbyś zachować jakiś alias po
to, by móc go używać następnym razem, musisz skorzystać ze skryptów, które są opisane w następnym
podrozdziale.
Skrypty powłoki
Skrypt jest prostym plikiem zawierającym polecenia systemu. Przechowywanie poleceń w plikach ułatwia ich
ponowne uruchamianie. Jako przykład rozważ skrypt o nazwie usuwacz, który zawiera następujące wiersze:
echo n Deleting the temporary files....
rm f *.tmp
echo Done
Polecenie echo powoduje wyświetlenie dowolnego tekstu na ekranie konsoli. Opcja n pierwszego polecenia
echo pomija znak śladu nowego wiersza zapisywanego zazwyczaj przez to polecenie, tak że oba polecenia
echo mogą wyświetlać swój tekst w osobnych wierszach. Drugi wiersz powoduje usunięcie z aktualnego
katalogu roboczego wszystkich plików tymczasowych zakończonych rozszerzeniem .tmp.
Możesz wykonać ten skrypt wydając polecenie:
sh usuwacz
Uwaga
Jeśli wydasz polecenie sh bez nazwy skryptu jako argumentu, zostanie uruchomiona nowa powłoka. Aby z
niej wyjść i powrócić do poprzedniej sesji, wpisz polecenie exit.
Jeśli plik usuwacz znajduje się w katalogu nie będącym na ścieżce $PATH, musisz podać bezwzględną nazwę
ścieżki, na przykład:
sh /home/jasio/usuwacz
Aby ułatwić wykonywanie skryptu, trzeba ustawić prawo wykonywania (x) dla użytkownika. Aby nadać
wszystkim użytkownikom takie prawo dostępu, wprowadz polecenie:
chmod a+x usuwacz
Teraz możesz wydać polecenie:
/home/jasio/usuwacz
Jeśli plik ten znajduje się w obecnym katalogu roboczym, możesz wpisać tylko:
./usuwacz
Zastanawiasz się zapewne, dlaczego nie możesz wydać takiego polecenia:
usuwacz
Wprawdzie jest to najprostsza forma uruchamiania poleceń, ale działa tylko w przypadku, gdy plik znajduje się
w katalogu wpisanym do ścieżki systemowej. O ścieżkach systemowych przeczytasz jeszcze w tym rozdziale.
System Linux zawiera kilka standardowych skryptów, które są uruchamiane o określonym czasie. Tabela 13.6
przedstawia skrypty i opisuje moment ich wykonywania. Możesz spowodować, aby działały inaczej. Na
przykład, jeśli chcesz ustanowić globalne aliasy, które będą uruchamiane niezależnie od tego, kiedy i gdzie
będziesz się logował, użyj dowolnego edytora tekstowego i wprowadz odpowiednie wiersze do pliku .profile,
który znajduje się w katalogu macierzystym. Przypomnij sobie, że, jeśli nazwy plików rozpoczynają się od
kropki, oznacza to, że polecenie ls nie wyświetli ich, dopóki nie podasz opcji a.
Tabela 13.6. Standardowe skrypty Linuksa
Skrypt Funkcja
/etc/profile Wykonywany w czasie logowania się użytkownika.
~/.profile Wykonywany w czasie logowania się użytkownika.
~/.bashrc Wykonywany podczas uruchamiania powłoki BASH.
~/.bash_logout Wykonywany w czasie operacji wylogowania.
Uwaga
Jeśli chcesz zmodyfikować jeden ze standardowych skryptów Linuksa, który powinien znajdować się w
katalogu roboczym, ale niestety go nie ma, po prostu go tam utwórz. Następnym razem, gdy się zalogujesz,
wylogujesz lub uruchomisz powłokę BASH, zostanie on uruchomiony.
Przekierowanie i przekazywanie wejścia-wyjścia
Powłoka obsługuje trzy strumienie danych:
" stdin standardowe wejście,
" stdout standardowe wyjście,
" stderr standardowy potok błędów.
Domyślnie, większość programów czyta dane wejściowe z stdin, a zapisuje wyjście do stdout. Ponieważ oba
strumienie są zwykle związane z konsolą, programy zachowują się dokładnie tak, jak im każesz; czytają dane
wejściowe z klawiatury i zapisują wyjście na ekranie konsoli. Kiedy program wyświetla komunikat o błędzie,
zapisuje go do strumienia stderr, który również jest związany domyślnie z konsolą. Oddzielny strumień dla
informacji wyjściowych i wiadomości o błędach ma bardzo ważne znaczenie, o czym się przekonasz.
Chociaż powłoka domyślnie wiąże trzy standardowe strumienie danych z konsolą, możesz przekierowywać
wejścia i wyjścia w taki sposób, że na przykład skierujesz wejście strumienia danych lub wyjście do pliku.
Tabela 13.7 podsumowuje najważniejsze tak zwane zwrotnice.
Tabela 13.7. Zwrotnice wejścia-wyjścia
Zwrotnica Funkcja
>plik
Wysyła standardowe wyjście do określonego pliku.
2>plik
Wysyła standardowy strumień błędów do określonego pliku.
>>plik
Wysyła standardowe wyjście do określonego pliku, dodając wyjście do pliku, jeśli ten już istnieje.
2>>plik
Wysyła standardowe strumień błędów do określonego pliku, dodając wyjście do pliku, jeśli ten
już istnieje.
&>plik
Wysyła standardowe wyjście i strumień błędów do określonego pliku.
Wysyła plik do standardowego wejścia programu.
<Czyta standardowe wejście aż znajdzie wiersz odpowiadający znakom tekst, przy którym
ogłaszany jest koniec pliku.
kmd1 |
Bierze standardowe wejście kmd2 (np. polecenie 2) ze standardowego wyjścia kmd1
kmd2
(pierwszego polecenia). Znak | jest również zwany przekierowaniem potoku lub po prostu
przekaznikiem.
Na przykładzie polecenia wc sprawdzimy, jak działają zwrotnice (pipes). Polecenie przyjmuje jako argument
nazwę pliku (lub kilku) i wyświetla odpowiednio: całkowitą liczbę wierszy, słów i znaków obecnych w pliku.
Zobaczmy:
wc /etc/passwd
powinieneś otrzymać:
16 20 570 /etc/passwd
co oznacza, że plik /etc/passwd zawiera 16 wierszy, 20 słów i 570 znaków. Wyjście polecenia pojawia się na
konsoli. Ale biorąc pod uwagę to samo polecenie, które zawiera zwrotnicę:
wc /etc/passwd > total
na konsoli nie pojawiły się żadne informacje, ponieważ wszystkie dane zostały skierowane i zapisane w pliku
total stworzonym przez polecenie (lub nadpisane, jeśli plik już istniał). Wydaj teraz dwa polecenia:
wc /etc/passwd > total
cat total
a zobaczysz wyjście polecenia wc na konsoli.
Być może rozumiesz już przyczynę, dlaczego warto mieć oddzielny strumień wyjścia stdout i stderr. Jeśli
powłoka posiada jeden strumień wyjścia, wiadomości o błędach oraz wyjście poleceń mogą się mieszać.
Dlatego, jeśli przekierujesz wyjście programu do pliku, każda informacja o błędzie zostanie też tam wysłana, co
spowoduje, że łatwo będzie przeoczyć błąd wykonywanego programu. Zamiast tego, mając dwa oddzielne
strumienie wyjścia, możesz przekierować tylko jedno z nich np. stdout do pliku. Kiedy tak zrobisz,
informacje o błędach wysyłane do stderr pojawiają się na konsoli. Oczywiście, jeśli wolisz, możesz skierować
stdout i stderr do tego samego pliku lub do dwóch różnych plików. Tak to już jest w systemie Unix, jak chcesz,
tak masz.
Prostą metodą uniknięcia drażliwych wiadomości jest skierowanie ich do pliku pustego /dev/null. Jeśli skierujesz
tam strumień stderr polecenia, nie zobaczysz żadnych informacji o jej błędach.
Tak jak można przekierować standardowe wyjście i strumień błędów polecenia do pliku, tak można również
skierować wejście polecenia do pliku, powodując, że polecenie będzie czytało np. argumenty z pliku, a nie z
konsoli. Wezmy polecenie wc bez żadnych argumentów; polecenie zacznie czytać dane ze standardowego
wejścia stdin. Wpiszmy więc kilka słów, a następnie naciśnijmy kombinację klawiszy Ctrl+D (jako znak
końca), a program wc wyświetli nam, ile wprowadziliśmy wierszy, słów i znaków. Możesz spowodować, żeby
wc czytał z pliku zamiast z konsoli, wydając takie polecenie:
wc Oczywiście nie jest to typowe wywołanie polecenia wc, ponieważ standardowo czyta ono dane z pliku, który jest
podawany jako argument. Natomiast jeśli nie podasz żadnego argumentu dla tego polecenia, wtedy czyta ono z
standardowego wejścia.
Uwaga
Niektóre programy są tak napisane, że ignorują zwrotnice. Na przykład polecenie passwd oczekuje
wprowadzenia hasła tylko z konsoli (teoretycznie z klawiatury), a nie np. z pliku. Istnieją oczywiście sposoby,
aby zmusić taki program do czytania z pliku, ale aby tego dokonać trzeba poznać bardziej skomplikowane
techniki niż zwrotnice.
Wiele jest takich programów, które, jeśli im nie podasz argumentów, czytają ze standardowego wejścia stdin, a
zapisują do standardowego wyjścia stdout. Takie programy nazywamy filtrami. Mogą być one łączone ze sobą w
celu wykonywania powiązanych zadań. Narzędziem do łączenia filtrów jest właśnie poznany wcześniej potok,
który łączy wyjście jednego programu z wejściem drugiego. Dla przykładu rozważmy polecenie:
ls l ~ | wc l
Polecenie to składa się z dwóch poleceń, połączonych za pomocą potoku (|). Pierwsze polecenie wyświetla
wszystkie pliki z katalogu domowego aktualnego użytkownika, po jednym pliku w wierszu. Drugie polecenie
uruchamia program wc z opcją l, która powoduje, że polecenie to wyświetla tylko liczbę wierszy i nie
przelicza słów i znaków. Potok wysyła wyjście polecenia ls do polecenia wc, które liczy i wyświetla liczbę
wierszy na wyjściu, co jest równe liczbę plików w danym katalogu.
Jest to bardzo prosty przykład doskonale oddający potęgę i wyrafinowanie powłoki Uniksa. Sam system nie
zawiera bowiem polecenia liczącego pliki w katalogu i nawet jej nie potrzebuje. Prawdopodobnie nigdy taki
program nie powstanie, ponieważ mało doświadczony użytkownik potrafi już napisać skrypt składający się z
poleceń systemu Unix.
Zmienne powłoki
Jeśli uczysz się programować, wiesz zatem, że programowanie przypomina algebrę. Język programowania i
algebra pozwalają bowiem odwołać się do wartości poprzez nazwę; posiadają również wyszukane mechanizmy
do manipulacji nazwanymi zmiennymi.
Powłoka jest językiem programowania posiadającym własne prawa. Pozwala odwoływać się do zmiennych
zwanych zmiennymi powłoki lub zmiennymi środowiskowymi. Aby przypisać wartość zmiennej powłoki, użyj
polecenia, które ma następującą składnię:
variable=value
Na przykład:
DifficultyLevel=1
przypisuje wartość równą 1 do zmiennej środowiskowej zwanej DifficultyLevel. W przeciwieństwie do
zmiennych algebraicznych, zmienne powłoki mogą posiadać wartości nienumeryczne. Na przykład:
Difficulty=medium
Zmienne środowiskowe są często używane w systemie Unix, ponieważ umożliwiają w prosty sposób
przeniesienie wartości z jednego polecenia do drugiego. Programy mogą otrzymywać wartości zmiennych i
używać ich do modyfikacji własnych operacji; w podobny sposób korzystają z podawanych przez użytkownika
argumentów.
Aby obejrzeć listę zmiennych środowiskowych, użyj polecenia set. Ponieważ może się zdarzyć, że będzie ich
dużo, możesz użyć potoku i polecenia more do oglądania wyjścia polecenia set ekran po ekranie:
set | more
Wciśnij Spację, aby zobaczyć następną stronę lub Enter, aby obejrzeć następny wiersz. Wśród tych zmiennych,
które zostaną wyświetlone na ekranie znajdziesz pewnie też te, które są przedstawione w tabeli 13.8. Wartości
tych zmiennych są generalnie ustawiane przez standardowe skrypty startowe powłoki, o których była wcześniej
już mowa.
Tabela 13.8. Ważne zmienne środowiskowe
Zmienna Funkcja
DISPLAY Używany serwer X, na przykład: localhost:0.
HOME Ścieżka bezwzględna katalogu domowego użytkownika.
HOSTNAME Internetowa nazwa komputera.
LOGNAME Nazwa logowania użytkownika.
MAIL Ścieżka bezwzględna katalogu poczty użytkownika.
PATH Ścieżka przeszukiwań (zobacz w następnej sekcji).
SHELL Ścieżka absolutna aktualnie używanej powłoki.
TERM Rodzaj terminalu.
USER Aktualna nazwa użytkownika, może się różnić od nazwy logowania, jeśli użytkownik
wydał polecenie su.
Wartość zmiennej środowiskowej możesz wstawić do polecenia, poprzedzając ją znakiem dolara ($). Aby nie
zmieszała się ona z otaczającym tekstem (argumentami, opcjami itp.), zamknij ją w nawiasach klamrowych
({}). Jest to dobry zwyczaj, aczkolwiek nie wymagany. Na przykład zmieńmy aktualny katalog roboczy na
katalog domowy za pomocą zmiennej HOME:
cd ${HOME}
Oczywiście wydanie polecenia cd bez żadnych argumentów da nam ten sam efekt. Jednakże załóżmy, że
chciałbyś zmienić aktualny katalog roboczy na podkatalog /praca znajdujący się w katalogu domowym.
Poniższe polecenie, pokazuje jak tego dokonać:
cd ${HOME}/praca
Najłatwiejszym sposobem na wyświetlenie wartości zmiennej środowiskowej jest podanie zmiennej jako
argumentu polecenia echo. Na przykład sprawdzmy, jaka jest wartość zmiennej HOME:
echo ${HOME}
Aby wartość zmiennej środowiskowej była dostępna nie tylko dla powłoki, ale także dla programów
wywoływanych poprzez powłokę, należy tę wartość wyeksportować. Aby tego dokonać, użyj polecenia
export:
export zmienna
gdzie zmienna oznacza nazwę zmiennej, którą chcesz eksportować. Podczas eksportowania zmiennej możesz
również nadać jej nową wartość:
export zmienna=wartość
Wartość zmiennej możesz usunąć, podając zmiennej pustą wartość (wartość zerową)
zmienna=
Jednakże zmienna środowiskowa mająca nawet wartość zerową nadal pozostaje zmienną powłoki i pojawia się
na wyjściu polecenia set. Aby ją stamtąd usunąć, wydaj polecenie:
unset zmienna
Teraz jej nie zobaczysz po wykonaniu polecenia set.
Ścieżki przeszukiwań
Specjalna zmienna powłoki PATH zawiera informacje na temat ścieżek zwanych ścieżkami przeszukiwań.
Gdziekolwiek nie wydasz polecenia zewnętrznego, powłoka sprawdza tę zmienną, czy aby nie zawiera ścieżki
umożliwiającej uruchomienie żądanego programu. Skrypty startowe ustanawiają początkową wartość zmiennej
środowiskowej PATH, którą następnie można dowolnie modyfikować. Do oddzielenia ścieżek użyj dwukropka
(:).
Na przykład załóżmy, że zmienna PATH przyjmuje następującą wartość:
/usr/bin:/bin:/usr/local/bin:/usr/bin/X11:/usr/X11R6/bin
Możesz zmodyfikować zmienną PATH, dodając nowy katalog przeszukiwań np. /home/magda w następujący
sposób:
PATH=${PATH}:/home/magda
Powłoka będzie szukała programów zewnętrznych także w katalogu /home/magda. Jednakże będzie to ostatni
katalog, do którego zajrzy. Jeśli chciałbyś, aby powłoka najpierw sprawdzała katalog /home/magda, wydaj
polecenie:
PATH=/home/magda:${PATH}
Programem pomocnym przy manipulowaniu zmienną PATH jest which. Sprawdza on ścieżkę dla określonego
pliku (który jest argumentem tego polecenia) i wyświetla nazwę pasującej ścieżki, jeśli taka istnieje. Na przykład
poszukajmy, gdzie znajduje się plik programu wc:
which wc
Na ekranie pojawić się powinna się ścieżka /usr/bin/wc lub inna zależna od wersji dystrybucji systemu Linux.
Aańcuchy notacji
Czasami powłoka może zle zinterpretować wydane polecenie, odwołując się do zmiennej, której wcale nie
zamierzałeś przywoływać, czy zle rozwijając nazwę pliku. Oczywiście nie jest to wina powłoki, tylko
prawdopodobnie błędnego wpisu. Dlatego tylko od ciebie zależy, czy powłoka będzie prawidłowo reagować na
polecenia.
Znaki notacji przedstawione w tabel 13.9 pomagają kontrolować działanie powłoki. Na przykład, jeśli zamkniesz
argument danego polecenia w pojedynczy cudzysłów, możesz zapobiec wykonywaniu na nim operacji
uogólnienia nazwy lub zamiany go na wartość zmiennej środowiskowej.
Tabela 13.9. Znaki notacji pomocne przy kontroli działań powłoki
Znak Funkcja
'
Znaki objęte parą pojedynczych cudzysłowów są interpretowane literalnie to znaczy ich znaczenie
metaznakowe (jeśli istnieje) jest ignorowane. Podobnie powłoka nie zamienia odnośników do
zmiennych środowiskowych na ich wartości.
"
Znaki objęte zwykłym cudzysłowem są również interpretowane literalnie, to znaczy, że ich znaczenie
metaznakowe (jeśli posiadają takowe) jest ignorowane. Jeśli chodzi o wartości zmiennych
środowiskowych, to są one wstawiane w miejsce ich wywołań.
`
Tekst objęty parą przeciwnych cudzysłowów jest interpretowany jak polecenie, które powłoka
wykonuje zanim przetworzy resztę wiersza polecenia. Wyjście polecenia zamienia oryginalny tekst
objęty tym cudzysłowem.
\
Znak ten jest interpretowany literalnie to znaczy, że jego metaznaczenie jest ignorowane. Znak tzw.
backslash (odwrotny slash) oznacza kontynuację poprzedniego wiersza. Kiedy wiersz polecenia
kończy się tym znakiem, obecny wiersz i następny są uważane za całość (jeden wiersz).
Sprawdzmy, jak to się wszystko odbywa w praktyce. Jako przykład wykorzystamy polecenie echo do
wyświetlenia napisu $PATH. Jeśli wydasz polecenie:
echo $PATH
program echo wyświetli wszystkie wartość zmiennej PATH. Jednakże zamykając argument polecenia echo w
pojedynczy cudzysłów, otrzymasz żądany rezultat:
echo '$PATH'
Cudzysłów przeciwny działa nieco inaczej, pozwala on wykonać polecenie i wykorzystać jego wyjście innemu
poleceniu. Na przykład polecenie:
echo Mój katalog domowy zawiera 'ls ~ | wc l' plików
wyświetla wiadomość, która podaje liczbę plików znajdujących się w katalogu domowym aktualnie
zalogowanego użytkownika. Polecenie to działa następująco najpierw wykonywane jest polecenie:
ls ~ | wc l
a ponieważ polecenie to jest zawarte w przeciwnym cudzysłowu, jego wynik nie jest wyświetlany na ekranie, ale
zastępuje oryginalny tekst objęty cudzysłowem.
następnie jest wykonywane polecenie:
echo Mój katalog domowy zawiera 48 plików
po zakończeniu wyjście polecenia przyjmuje postać:
Mój katalog domowy zawiera 48 plików.
Potęga powłoki Linuksa
Mam nadzieję, że zaczynasz powoli doceniać siłę powłoki systemu Linux; dołączając aliasy poleceń do pliku
.bashrc możesz rozszerzyć zakres poleceń powłoki. Przy użyciu dopełniania nazw plików i listy historii możesz
zredukować ilość niepotrzebnych znaków wprowadzanych z klawiatury do minimum. Kiedy już dowiesz się, jak
poprawnie używać wszystkich tych właściwości, okaże się, że powłoka jest silnym, szybkim i bardzo łatwym w
użyciu interfejsem użytkownika, który nie jest tak monotonny i ograniczony jak interfejs graficzny oparty na
klikaniu.
Co więcej, powłoka posiada dodatkowe funkcje, które jeszcze bardziej rozszerzają obszar jej zastosowań. Jak
zobaczysz w następnym podrozdziale, powłoka systemu Linux zawiera wydajny język programowania, który
umożliwia przetwarzanie argumentów, tworzenie pętli i stawiania warunków logicznych.
Poznawanie skryptów powłoki
Podrozdział wyjaśnia, jak działają bardziej zaawansowane skrypty powłoki. Informacje są przedstawione po to,
abyś szybko i wydajnie mógł pisać własne skrypty. Rozpoczynamy od przetwarzania argumentów skryptów, a
następnie przejdziemy do operacji warunkowych i logicznych.
Przetwarzanie argumentów
Z łatwością można napisać program, który będzie przetwarzał argumenty, ponieważ istnieje zestaw specjalnych
zmiennych powłoki, który zawiera wartości dla argumentów określanych podczas inicjalizacji skryptu. Tabela
13.10 przedstawia te zmienne.
Oto prosty program, który wyświetla wartość swojego drugiego argumentu:
echo Mój drugi argument ma wartość $2
Załóżmy, że zapiszesz ten skrypt do pliku o nazwie drugi; zmień tryb dostępu tak, aby mógł być wykonywany
i wydaj polecenie:
./drugi a b c
Na wyjściu pojawi się wynik tej operacji:
Mój drugi argument ma wartość b
Tabela 13.10. Specjalne zmienne powłoki
Zmienna Znaczenie
$#
Liczba argumentów
$0
Nazwa polecenia
$1, $2,...,$9
Indywidualne argumenty polecenia
$*
Cała lista argumentów, traktowana jako pojedyncze słowo
$@
Cała lista argumentów, traktowana jako seria słów
$?
Status wyjścia poprzedniego polecenia. Wartość 0 oznacza pomyślne zakończenie
(wyjście)
$$
Id (identyfikator) aktywnego procesu
Zwróć uwagę na fakt, że powłoka pozwala odwołać się bezpośrednio tylko do dziewięciu argumentów. Niemniej
jednak istnieje możliwość przywołania większej liczby argumentów. Służy do tego polecenie shift, które
odrzuca wartość pierwszego argumentu i przesuwa pozostałe wartości o jedną pozycję w dół (lub do góry). Tym
sposobem po wykonaniu polecenia shift zmienna powłoki $9 zawiera wartość dziesiątego argumentu. Aby
przywołać jedenasty lub każdy następny argument, należy wykonać polecenie shift odpowiednią ilość razy.
Kody wyjścia
Zmienna powłoki $? utrzymuje numeryczny status wyjścia dla każdego ostatnio wykonanego polecenia. Zasada
jest taka, że wartość zerowa tej zmiennej oznacza pomyślne zakończenie programu, tymczasem każda inna
wartość oznacza nieprawidłowe wykonanie polecenia.
Kod błędu możesz ustawić w skrypcie, za pomocą polecenia exit, które kończy pracę skryptu podając
określony status wyjścia. Składnia exit jest następująca:
exit status
gdzie status jest nieujemną liczbą całkowitą, która określa status wyjścia.
Logika warunkowa
Skrypty powłoki mogą używać logiki warunkowej, która pozwala im podejmować różne działania w zależności
od wartości argumentów, zmiennych środowiskowych lub ich warunków. Na przykład polecenie test pozwala
określić warunek, który może być albo prawdziwy, albo fałszywy. Wszystkie polecenia warunkowe (włączając
if, case, while oraz until) używają polecenia test do szacowania warunków.
Polecenie test
Tabela 13.11 przedstawia opis niektórych powszechnie stosowanych form argumentów używanych do polecenia
test. Polecenie sprawdza argumenty i ustawia kod wyjściowy na zero, co oznacza, że dany warunek był
prawdziwy lub podaje wartość większą od zera, która mówi, że warunek był nieprawdziwy.
Tabela 13.11. Powszechnie używane formy argumentów polecenia test
Forma Funkcja
-d plik
Określony plik istnieje i jest katalogiem
-e plik
Określony plik istnieje
-r plik
Określony plik istnieje i jest do odczytu
-s plik
Określony plik istnieje i ma niezerowy rozmiar
-w plik
Określony plik istnieje i jest do zapisu
-x plik
Określony plik istnieje i jest wykonywalny
-L plik
Określony plik istnieje i jest dowiązaniem symbolicznym
f1 -nt f2
Plik f1 jest nowszy niż plik f2
f1 -ot f2
Plik f1 jest starszy niż plik f2
-n s1
Aańcuch s1 ma niezerową długość
-z s1
Aańcuch s1 ma zerową długość
s1 = s2
Aańcuch s1 jest taki sam jak s2
s1 =! s2
Aańcuch s1 nie jest taki sam jak s2
n1 -eq n2
Liczba całkowita n1 jest równa liczbie n2
n1 -ge n2
Liczba całkowita n1 jest większa bądz równa liczbie n2
n1 -gt n2
Liczba całkowita n1 jest większa niż liczba n2
n1 -le n2
Liczba całkowita n1 jest mniejsza bądz równa liczbie całkowitej n2
n1 -lt n2
Liczba całkowita n1 jest mniejsza niz liczba n2
n1 -ne n2
Liczba n1 nie jest równa liczbie n2
!
Operator przeczenia (not nie), który odwraca wartość danego warunku
-a
Operator łączności (and i), który łączy dwa warunki. Oba warunki muszą być
prawdziwe, aby całkowity rezultat dał prawdziwy wynik
-o
Operator alternatywy, który łączy dwa warunki. Jeśli jeden z dwóch warunków jest
prawdziwy, wynik jest rownież prawdziwy
\( ... \)
Wyrażenia w poleceniu test można grupować zamykając je w \( i \)
Dla przykładu rozważmy taki skrypt:
test d $1
echo $?
Skrypt ten sprawdza, czy pierwszy argument określa katalog i wyświetla status wyjścia, wartość zero lub inną w
zależności od wyniku testu.
Załóżmy, że powyższe polecenia są przechowywane w pliku tester, który posiada atrybut do odczytu oraz do
wykonania. Wykonanie tego skryptu może dawać następujące wyniki:
$ ./tester /
0
$ ./tester /missing
1
Oznaczają one odpowiednio: 0 katalog / istnieje, a wartość 1 katalog /missing nie istnieje.
Polecenie if
Samo polecenie test nie jest zbyt przydatne, chyba że zostanie użyte w połączeniu z innymi instrukcjami
warunkowymi na przykład z poleceniem if. Składnia polecenia if jest następująca:
if polecenie
then
polecenia
else plecenia
fi
Zazwyczaj poleceniem, które występuje bezpośrednio po poleceniu if jest test. Jednakże, nie jest to
warunkiem koniecznym. Polecenie if jedynie wykonuje określoną warunki i sprawdza status wyjścia. Jeśli jest
on równy 0, wykonywany jest pierwszy zestaw poleceń, jeśli nie wykonywany jest drugi zestaw. Skrócona
forma polecenia if nie robi nic, jeśli określony warunek jest nieprawdziwy.
if polecenie
then
polecenie
fi
Kiedy wpisujesz polecenie if, zajmuje ono kilka wierszy, a jednak jest uważane za pojedyncze polecenie. Do
wprowadzania takich poleceń, powłoka dostarcza specjalnego znaku zachęty (zwanego czasami drugim znakiem
zachęty) po wprowadzeniu każdego wiersza. Często skrypty są tworzone za pomocą edytorów tekstowych,
wtedy nie są widoczne dodatkowe znaki zachęty powłoki.
Dla przykładu spróbujmy usunąć plik1, jeśli jest on starszy niż plik2. Poniższe plecenie powinno poprawnie
rozwiązywać to zadanie:
if test plik1 ot plik2
then
rm plik1
fi
Polecenie możesz dołączyć do skryptu, który akceptuje argumenty określające nazwy plików:
if test $1 ot $2
then
rm $1
echo Usunięto stary plik
fi
Możesz zapisać polecenie do pliku o dowolnej nazwie np. usuwacz i wykonać go:
./usuwacz plik1 plik2
A skrypt usunie plik1, jeśli jest on starszy od pliku2.
Polecenie case
Polecenie case dostarcza bardziej wyrafinowanej metody przetwarzania warunkowego:
case wartość in
wzorzec1) polecenia ;;
wzorzec2) polecenia ;;
...
esac
Polecenie przestępuje do przystępuje do wyszukiwania określonych wartości odpowiadających podanym
wzorom (wzorzec1, wzorzec2). Jeśli istnieje odpowiednik pierwszego wzoru, polecenie związane z nim zostanie
wykonane. Wzory budowane są przy użyciu znaków i metaznaków, takich jak te używane do określania
argumentów poleceń. Przyjrzyjmy się poleceniu case, którego zadaniem jest zinterpretowanie wartości
pierwszego argumentu skryptu:
case $1 in
-r) echo Wymuś usuwanie bez potwierdzania ;;
-i) echo Potwierdz przed usunięciem ;;
*) echo Nieznany argument ;; esac
Polecenie wyświetla wiadomość zależnie od wartości pierwszego argumentu skryptu. Dobrym ćwiczeniem jest
dołączenie do tego przykładu końcowego wzoru, który odpowiadałby każdej wartości argumentu skryptu.
Polecenie while
Pozwala ono na wykonywanie serii poleceń iteracyjnie, to znaczy wielokrotnie, dopóki sprawdzane warunki
będą prawdziwe:
while polecenie
do
polecenia
done
Oto skrypt, który używa polecenia while do wyświetlania własnych argumentów w kolejnych wierszach:
echo $1
while shift 2>/dev/null
do
echo $1
done
Część polecenia while obejmująca pętlę do może także zawierać polecenia if, case a nawet kolejne
polecenie while. Jednakże w tym ostatnim przypadku, skrypt taki robi się szybko nieczytelny. Powinieneś
stosować polecenia warunkowe razem tylko dla osiągnięcia jasnych wyników. Możesz dołączać komentarze
wszędzie tam, gdzie wstawiasz zawikłane konstrukcje warunkowe.
Polecenie until
Polecenie działa na niemalże identycznej zasadzie jak while, z jednym tylko wyjątkiem pozwala
mianowicie wykonywać serie poleceń iteracyjnie, dopóki sprawdzane warunki są fałszywe.
until polecenie
do
polecenia
done
Spójrz na skrypt, który używa polecenia until do wyświetlania własnych argumentów w kolejnych wierszach,
aż nie pojawi się argument o wartości czarny:
until test $1 = "czarny"
do
echo $1
shift
done
Jeśli zapiszemy ten skrypt do pliku o nazwie kolorki w katalogu roboczym, to polecenie:
./kolorki zielony niebieski żółty czarny czerwony
wyświetli nam taki oto wynik:
zielony
niebieski
żółty
Polecenie for
Polecenie iteruje (powtarza, zapętla) elementy określonej listy:
for zmienna in lista
do
polecenia
done
Za pomocą poleceń możesz odwołać się do aktualnego elementu listy poprzez zmienną powłoki $zmienna.
Lista zazwyczaj przyjmuje formę serii argumentów, które mogą zawierać metaznaki. Rozważmy na przykład
taką instrukcję:
for i in 2 4 6 8
do
echo $i
done
Wyświetla ona wartości 2 4 6 8 w kolejnych wierszach.
Specjalna forma tego polecenia iteruje argumenty dowolnego skryptu:
for zmienna
do
polecenia
done
Na przykład następny skrypt wyświetla własne argumenty w kolejnych wierszach:
for i
do
echo $i
done
Polecenia break oraz continue
Są to proste polecenia i nie przyjmują żadnych argumentów. Kiedy powłoka dostrzeże polecenie break,
natychmiast wychodzi z pętli (while, until, for). Kiedy natomiast powłoka napotka polecenie continue,
natychmiast przerywa aktualną iterację pętli. Jeśli warunki pętli na to pozwalają, wykonane mogą zostać inne
powtórzenia pętli; w przeciwnym razie następuje wyjście z pętli.
Peryskop: użyteczny skrypt sieciowy
Załóżmy, że posiadasz darmowe konto e-mail, na przykład w Yahoo. Jesteś akurat w podróży i posiadasz
jedynie zdalny dostęp do sieci Internet. Jednakże nie jesteś w stanie wykonywać żadnych operacji na plikach
znajdujących się na komputerze domowym, ani też odebrać poczty, która tam przyszła. To typowe okoliczności,
zwłaszcza jeśli jesteś w podróży (wymaga tego na przykład twoja praca).
Jeśli posiadasz w domu komputer działający pod kontrolą systemu Microsoft Windows, no to nie masz za dużo
szczęścia. Jeśli nie zakupisz odpowiedniego oprogramowania, bardzo ciężko ci będzie uzyskać dostęp do
znajdujących się tam plików i poczty. Jednakże jeśli to Linux jest systemem operacyjnym tego komputera, to nie
będzie żadnych problemów.
W celu przedstawienia możliwości powłoki w podrozdziale tym opisano bardziej złożony skrypt zwany
peryskopem. Jest to program, który w określonym czasie każdego dnia ustanawia połączenie z Internetem. Takie
połączenie za pomocą sesji PPP może być utrzymywane przez godzinę lub więcej, zależy, ile czasu potrzebujesz
na połączenie się z Internetem z miejsca, w którym się znajdujesz, i wykonanie wszystkich żądanych operacji.
Kiedy już się połączysz, możesz pobrać pocztę lub przejrzeć ją zdalnie i wykonać inne zadania. Po upływie
ustalonego czasu, program peryskop przerywa połączenie PPP, które zostanie nawiązane ponownie następnego
dnia o tej samej porze.
Przykład 13.1 przedstawia zawartość pliku peryskop, który, jak widzisz, jest zdecydowanie dłuższy i bardziej
złożony niż jakikolwiek skrypt opisywany w tym rozdziale. W związku z tym wyjaśnimy działanie skryptu
wiersz po wierszu. Jak zobaczysz, skrypt ten ma bardzo prostą i przejrzystą budowę.
Przykład 13.1. Peryskop
PATH=${PATH}:/usr/local/bin
route del default
wvdial &
sleep 1m
ifconfig | mail userid@mail.com
sleep 1h
killall wdial
sleep 2s
killall 9 wvdial
killall pppd
sleep 2s
killall 9 pppd
echo "/root/peryskop" | at 10:00
Pierwszy wiersz określa ścieżkę poszukiwań dla skryptu, która ustawia katalog /usr/local/bin zawierający
polecenie zewnętrzne powłoki wvdial. Niektóre skrypty startowe systemu Linux mogą nie zawierać tej ścieżki,
więc bezpośrednie umieszczenie jej w tym programie zapobiegnie powstawaniu błędów na samym jego starcie.
PATH=${PATH}:/usr/local/bin
Następny wiersz jest prawdopodobnie najbardziej skomplikowany:
route del default
Polecenie route jest zazwyczaj stosowane przez administratora systemu. Prawdopodobnie nie używałeś nigdy
tego polecenia, ponieważ program konfigurujący sieć robił to za ciebie. Efektem tego polecenie jest usunięcie
domyślnej trasy sieciowej, jeśli taka istnieje. Domyślna trasa jest to taka droga wysyłanych pakietów TCP/IP,
która nie zawiera informacji o trasie do określonych miejsc przeznaczenia tych pakietów. Należy ją usunąć z
tego względu, że program wvdial, którego skrypt używa do nawiązania sesji PPP, jej nie zmieni, ani też nie
usunie.
wvdial &
Powyższy wiersz uruchamia program wvdial w tle (co określa znak &), tak że skrypt może dalej działać (tzn.
wykonywać inne działania). Następny wiersz zatrzymuje działanie skryptu na jedną minutę po to, aby wvdial
nawiązał połączenie PPP.
sleep 1m
Kolejny wiersz uruchamia polecenie ifconfig i wysyła wiadomość e-mail do określonego użytkownika
zawierającą wyjście tego programu (należy przy tym zastąpić userid@mail.com własnym adresem e-mail).
ifconfig | userid@mail.com
Polecenie ifconfig produkuje wyjście, które wygląda mniej więcej tak:
ppp0 Link encap:Point-Point Protocol
inet addr: 10.144.153.105 P-t-P: 10.144.153.52 Mask: 255.255.255.0
UP POINTOPOINT RUNNING MTU: 552 METRIC: 1
RX packets: 0 errors: 0 dropped: 0 overruns: 0
TX packets: 0 errors: 0 dropped: 0 overruns: 0
Zobaczysz pewnie inne sekcje opisujące interfejs Ethernet (eth0) oraz urządzenie zwrotne lo. Zmienna inet
addr o wartości 10.144.153.105 oznacza adres IP twojego komputera. Wysyłając e-mail zawierający wyjście
polecenia ifconfig otrzymujesz informacje o adresie IP komputera domowego, który jest zmieniany za
każdym razem, kiedy łączysz się z Internetem przy użyciu usługi PPP.
Kolejny wiersz powoduje zatrzymanie działanie skryptu na jedną godzinę.
sleep 1h
Oczywiście nie musi to być jedna godzina, możesz ustawić dowolny czas.
Kiedy już zostanie przekroczony czas pauzy programu, zaczyna on zamykać wszystkie uruchomione zadania
programu wvdial:
killall wvdial
Uwaga
Dodatek E Krótki podręcznik poleceń Linuksa dokładnie opisuje polecenie killall i inne nieznane polecenia
zawarte w tym skrypcie.
Następnie skrypt zatrzymuje się na dwie sekundy po to, aby program wvdial zakończył poprawnie wszystkie
operacje.
sleep 2s
W niektórych przypadkach, program może zignorować żądanie przerwania działania. Poniższy wiersz zapewnia
jednak natychmiastowe zamknięcie programu wvdial, wysyłając specjalny sygnał, który kończy aktywny
proces bezwarunkowo.
killall 9 wvdial
Wiadomo, że w tle program wvdial uruchamia także program pppd, który nawiązuje i zarządza połączeniem
PPP. Kolejne polecenie killall zostaje wydana w celu przerwania połączenia i zamknięcia programu pppd,
jeśli program wvdial tego nie zrobił:
killall pppd
Na końcu, skrypt korzysta z polecenia at, aby wyznaczyć następną datę swojego uruchomienia (domyślnie jest
jutro):
echo "/root/peryskop" | at 10:00
Polecenie at odczytuje ze standardowego wejścia polecenie echo (a dokładnie jej wyjście: /root/peryskop) i
wykonuje je w określonym czasie (10:00).
Aby wypróbować skrypt, musisz zainstalować program wvdial; jego instalację i konfigurację przedstawiono w
rozdziale 11. Podłączanie do sieci Internet . Umieść skrypt w katalogu /root pod nazwą peryskop. Jeśli chcesz
wprowadzić jakieś zmiany (np. czasu rozpoczęcia lub trwania połączenia), otwórz skrypt w dowolnym edytorze
i dokonaj odpowiednich poprawek. Aby uruchomić program, zaloguj się na użytkownika root i wydaj polecenie:
(echo "/root/peryskop" | at 10:00) &
Kiedy wybije godzina 10:00 (lub ta którą ustawiłeś), system Linux powinien rozpocząć nawiązywanie
połączenia z ISP i utrzymywać je przez określony czas.
Używanie peryskopu
Kiedy nadejdzie określony czas, uruchom komputer i połącz się ze swoim kontem poczty. Powinieneś znalezć
wiadomość zawierającą wyjście programu ifconfig wraz z adresem IP komputera domowego. Teraz możesz
użyć programu telnet lub ssh wybór zależy od tego, który serwer masz uruchomiony na komputerze
domowym aby połączyć się ze swoim komputerem i pracować przez wyznaczony czas. Pod koniec
wyznaczonego czasu system Linux rozpocznie rozłączanie i ustali datę i czas kolejnego połączenia.
Co dalej?
Jak łatwo zauważyć, peryskop nie jest bardzo skomplikowanym skryptem przez co nie odzwierciedla pełnych
możliwości systemu Linux. Na przykład załóżmy, że chciałbyś ustanowić połączenie o różnych porach dnia lub
różnych dniach tygodnia albo chciałbyś ustalić pewien harmonogram połączeń za każdym razem, kiedy się
logujesz.
Linux jest w stanie sprostać takim wymaganiom na różne sposoby. Na przykład program cron, który jest trochę
bardziej zaawansowany niż at, umożliwia bardzo elastyczne określanie czasu uruchomienia programów.
Pozwala on między innymi ustanowić połączenie o określonej porze w każdy trzeci piątek miesiąca.
Więcej na temat Linuksa dowiesz się po przeczytaniu dodatku E Krótki podręcznik poleceń Linuksa , w
którym opisano wiele pożytecznych poleceń systemu Linux, które możesz użyć w skryptach. Najlepszą metodą
poznania tych poleceń jest dokładne przeczytanie tego rozdziału. Należy także przynajmniej zajrzeć do ich stron
podręczników, na pewno znajdziesz tam wiele interesujących informacji.
Jeśli złapałeś linuksowego bakcyla, co zdarzyło się wielu użytkownikom komputerów, polecam ci inne książki o
tym systemie:
" Debian Linux. Księga Eksperta wydana przez Wydawnictwo Helion, 2001.
" Linux. Praktyczne rozwiązania wydana przez Wydawnictwo Helion, 2000.
" Linux dla stacji roboczych wydana przez Wydawnictwo Helion, 1999.
" Linux wydana przez Wydawnictwo Helion, 1998.
Mnóstwo informacji na temat Linuksa znajdziesz na stronach WWW opisanych w rozdziale 1. Dlaczego
Linux? oraz w czasopismach Linux Journal i Linux Magazine.
Jednakże, nie czytaj tylko o Linuksie, pracuj z nim. Pisz, testuj i debuguj własne skrypty. Dziel się napisanymi
skryptami z innymi użytkownikami tego systemu oraz studiuj skrypty innych. Ponadto czytaj wiadomości grup
dyskusyjnych i komunikuj się z innymi ludzmi; dziel się tym, czego się dowiedziałeś i pytaj o to, co chcesz
wiedzieć. Takie postępowanie stało się fundamentem kultury ludzi związanych z systemem Linux, o czym
zapewne przekonasz się już sam.
Wyszukiwarka
Podobne podstrony:
Powłoka BASH
Rozdział 13
Rozdział 13 (tł Kath)
15 Rozdzial 13
Wings of the wicked rozdział 13
rozdzial$ (13)
14 Rozdział 13
Siderek12 Tom I Część III Rozdział 13
ROZDZIAŁ 13 Nerwiakowłókniakowatość
15 Rozdzial 13
Frysztacki, konspekt z rozdziałów 13 16
więcej podobnych podstron