Laboratorium Architektury Komputerów
i Systemów Operacyjnych
Ćwiczenie 6
Polecenia systemu Unix/Linux, łączenie poleceń,
programowanie w języku powłoki
Uwaga: niniejsza instrukcja składa się z dwóch części A i B. W celu uzyskania
zaliczenia ćwiczenia laboratoryjnego wystarczy wykonać zadania z części A
albo z części B (bardziej zaawansowanej).
Wprowadzenie
System operacyjny Linux należy do rodziny systemów uniksopodobnych. System
Unix powstał w 1969 r. w laboratoriach firmy ATT. Na przestrzeni minionych lat stał się
jednym z głównych systemów operacyjnych stosowanych w stacjach roboczych, serwerach
obliczeniowych, serwerach sieciowych, itp. Powstało wiele wersji systemu, nieznacznie
różniących się ze względu na ograniczenia patentowe i licencyjne. Pojawiły się także wersje
na procesory rodziny x86, np. SCO Unix (firmy później wykupionej przez SUN).
Linux powstał w 1991 roku, gdy fiński informatyk Linus Torvald poinformował o
utworzeniu przez siebie hobbystycznego systemu operacyjnego na procesory i386/486.
Powstały system tylko z zewnątrz (od strony użytkowej) przypominał Unix, natomiast
wewnątrz prezentował zupełnie inną koncepcję w zakresie rozwiązań technicznych. Był
oparty o jądro, które było konfigurowane do konkretnych zastosowań i następnie
kompilowane. Do jądra dołączono biblioteki pochodzące z projektu GNU (ang. GNU means
Not Unix). Dzięki temu system działał szybciej od porównywalnych rozwiązań uniksowych.
Linux jest jednym z przykładów wolnego i otwartego oprogramowania, a jego kod
może być dowolnie wykorzystywany, modyfikowany i rozpowszechniany (opensource –
licencja GNU PL). Obecnie jest on udostępniany w formie licznych dystrybucji Linuksa (np.
Debian, Red Hat, Suse, Ubuntu), które składają się z jądra (niekiedy zmodyfikowanego w
stosunku do oficjalnej wersji) i zestawu pakietów oprogramowania dobranego do
różnorodnych wymagań. Dystrybucje zawierają głównie oprogramowanie na licencjach
opensource, ale można dodać do nich oprogramowanie licencjonowane.
Linuks jest często stosowany w serwerach sieciowych (poczta, ftp, zapory sieciowe,
serwisy www, systemy NIDS i HIDS), ale także jest stosowany w multimediach (systemy
wbudowane, np. w urządzeniach DVD, telefonach, i-podach) i w dużych systemach
wielomaszynowych i wieloprocesorowych (np. TASK, symulacje filmowe). Korzystają z
niego urzędy administracji państwowej (ale nie w Polsce), służby specjalne, organizacje
biznesowe, np. giełdy.
Linuks oferuje wiele możliwości pracy z systemem. Można tworzyć dokumenty i
prezentacje, używając pakietu OpenOffice (obecnie LibreOffice – nie jest częścią Linuksa),
grafikę, a także administrować zasobami systemu z poziomu interfejsu okienkowego oraz
terminalowego. Ten ostatni sposób bezpośrednio wywodzi się z systemu Unix – był przez
2
2
długi okres czasu jedyną metodą komunikacji z systemem operacyjnym. W niektórych
specjalizowanych zastosowaniach (np. systemy wbudowane, urządzenia sieciowe, itp.) jest to
jedyny interfejs systemu.
Informacje wstępne
Celem ćwiczenia laboratoryjnego nr
6 jest:
poznanie przez uczestników
zajęć podstawowych poleceń
systemu UNIX,
poznanie roli zmiennych otoczenia,
poznanie i utrwalenie wiedzy dotyczącej budowy systemu operacyjnego, struktury
katalogów, zasad realizacji poleceń;
wprowadzenie do programowania w języku powłoki.
Realizacja omawianego ćwiczenia laboratoryjnego wymaga:
znajomości metod uruchamiania programów w środowisku Windows/Linux,
umiejętności programowania w języku C,
znajomości podstawowych pojęć z architektury systemów komputerowych.
Do wykonania niniejszego ćwiczenia używane będą narzędzia programistyczne dostępne w
laboratoriach Wydziału ETI PG.
Aby zaliczyć ćwiczenia laboratoryjne, student musi wykonać poprawnie polecenia i zadania
podane przez prowadzącego (w ramach części A albo B).
Plik zawierający niniejszą instrukcję (AKiSO_lab6.pdf) dostępny jest na serwerze
\\mkzl\public\AKiSO. W celu odczytania zawartości tego pliku w systemie Linux
należy wykonać niżej opisane czynności:
1. Otworzyć okno terminala. Po wpisaniu każdego polecenia nacisnąć klawisz Enter.
2. Wprowadzić polecenie:
smbclient //mkzl4/public
3. W odpowiedzi na zapytanie „Enter student’s password” nacisnąć Enter (nic nie
wpisywać).
4. Wpisać polecenie cd AKiSO
5. Wpisać polecenie get AKiSO_lab6.pdf
6. Wpisać polecenie quit
7. Otworzyć przeglądarkę internetową i wpisać file:///home/student — w
rezultacie w oknie przeglądarki zostanie wyświetlona zawartość katalogu
home/student. Należy wówczas kliknąć na plik AKiSO_lab6.pdf.
Uwaga
: przykłady podane w instrukcji można
kopiować i przenosić do edytowanych
skryptów, ale znaki apostrofów, cudzysłowów i
znak minus
– mogą ulegać zniekształceniu. Z
tego powodu po skopiowaniu ww. znaki nal
eży
wpisać ponownie z klawiatury.
3
3
Część A: Podstawowe polecenia systemu Unix/Linux
Polecenie składa się z następujących elementów:
<nazwa_polecenia> -<opcje> <parametry>
gdzie:
<nazwa_polecenia> jest nazwa jakiegokolwiek programu, funkcji powłoki lub funkcji
wewnętrznej powłoki.
<opcje> to najczęściej zestaw pojedynczych liter określających sposób wykonania
programu.
<parametry> to informacje dla programu (funkcji) co właściwie ma wykonać.
Uwaga: w składni polecenia pomiędzy nazwą polecenia, opcjami i parametrami występuje co
najmniej jedna spacja – nie można jej pominąć – pełni ona rolę separatora pomiędzy
elementami polecenia.
Uwaga: w systemie jest dostępny podręcznik opisujący działanie poleceń systemowych. W
celu uzyskania informacji należy wprowadzić polecenie postaci:
man <nazwa_polecenia>
Przykładowo, wpisanie:
man ls
spowoduje wyświetlenie opisu polecenia ls wraz z opcjami dostępnymi w danej wersji
systemu.
Polecenie cd
Polecenie to służy do zmiany aktualnego katalogu. Jeśli nie podamy argumentu, domyślnie
przyjmowany jest katalog domowy podany w zmiennej $HOME. Katalog / oznacza główny
katalog systemu Linux/Unix.
Polecenie ls – wyświetl zawartość katalogu
Jeśli nie podamy żadnego argumentu, zostanie wyświetlona zawartość katalogu aktualnego
(miejsca, w którym aktualnie „znajduje się” użytkownik). Często stosowane opcje (pozostałe
opisane są w podręczniku man):
-R
rekursywnie wyświetlaj poddrzewo;
-a
wyświetl wszystkie pozycje katalogu, nawet rozpoczynające się od '.';
-d
nie listuj zawartości katalogów;
-i
podaj numery węzłów dla plików;
-l
długi listing: tryb (typ i uprawnienia), liczba łączników, właściciel, grupa,
wielkość, czas ;
-r
odwróć porządek sortowania;
-s
podaj wielkość w blokach;
-t
sortuj w/g czasu, najnowsze na początku.
4
4
Po wpisaniu poleceń
cd /
ls –l
otrzymujemy następujący wydruk (w przybliżeniu – dla różnych wersji systemu Linux może
wyglądać nieznacznie inaczej) na ekranie terminala głównego katalogu systemowego:
razem 80
drwxr-xr-x 2 root root 4096 2008-10-07 22:25 bin
drwxr-xr-x 3 root root 4096 2008-10-28 18:31 boot
lrwxrwxrwx 1 root root 11 2008-10-07 21:30 cdrom -> media/cdrom
drwxr-xr-x 13 root root 4280 2009-03-06 12:03 dev
drwxr-xr-x 108 root root 4096 2009-03-06 12:02 etc
drwxr-xr-x 3 root root 4096 2008-10-07 22:30 home
drwxr-xr-x 2 root root 4096 2008-10-07 21:32 initrd
lrwxrwxrwx 1 root root 28 2008-10-07 21:34 initrd.img ->
boot/initrd.img-2.6.18-6-686
drwxr-xr-x 15 root root 4096 2008-10-07 22:25 lib
drwx------ 2 root root 16384 2008-10-07 21:30 lost+found
drwxr-xr-x 4 root root 4096 2008-11-12 13:33 media
drwxr-xr-x 2 root root 4096 2006-10-28 16:06 mnt
drwxr-xr-x 2 root root 4096 2008-10-07 21:32 opt
dr-xr-xr-x 144 root root 0 2009-03-06 13:02 proc
drwxr-xr-x 8 root root 4096 2008-11-17 20:15 root
drwxr-xr-x 2 root root 4096 2008-10-07 22:30 sbin
drwxr-xr-x 2 root root 4096 2007-03-07 23:56 selinux
drwxr-xr-x 2 root root 4096 2008-10-07 21:32 srv
drwxr-xr-x 11 root root 0 2009-03-06 13:02 sys
drwxrwxrwt 10 root root 4096 2009-03-06 12:17 tmp
drwxr-xr-x 11 root root 4096 2008-10-07 22:20 usr
drwxr-xr-x 15 root root 4096 2008-10-07 22:28 var
lrwxrwxrwx 1 root root 25 2008-10-07 21:34 vmlinuz -> boot/vmlinuz-
2.6.18-6-686
Zadania do wykonania:
a. W podobny sposób obejrzyj zawartość katalogów dev, etc, bin, usr. Jak
interpretujemy ich zawartość?
b. Po wpisaniu poleceń
cd $HOME
ls –a
otrzymujemy wydruk na ekranie terminala katalogu domowego. Porównaj wydruki po
wykonaniu polecenia: ls –l. Jaką widzisz różnicę? Co oznaczają pliki o nazwie
zaczynającej się od znaku kropki?
Polecenie pwd
Polecenie pwd wyświetla na konsoli bieżący katalog. Na przykład, kiedy wykonamy
polecenie cd /usr/bin i użyjemy polecenia pwd, to zobaczymy na ekranie /usr/bin
5
5
Polecenie cat – połącz (concatenate) i wyświetl pliki
Polecenie wyświetla kolejno na standardowym wyjściu (ekran terminala) kolejne pliki,
których nazwy są umieszczone w wierszu polecenia. Możemy wyświetlane pliki połączyć w
jeden nowy plik, przekierowując odpowiednio standardowe wyjście, np.:
cat plik1 plik2 plik3 > plik4
//połącz trzy pliki w jeden
Znaki // oddzielają komentarz od polecenia i nie są interpretowane.
Uwaga: polecenie cat można w tej formie używać zamiennie z poleceniem cp (kopiuj
pliki), np.
cat prog.c >prog1.c
spowoduje skopiowanie pliku prog.c do pliku prog1.c. Jeśli plik prog1.c istniał przed
wykonaniem tego polecenia, to jego poprzednia zawartość zostanie usunięta.
Ponadto polecenia cat można użyć do tworzenia nowego pliku, np.
cat > nowy.txt
Ponieważ nie podano pliku wejściowego, to będzie nim standardowe wejście (klawiatura).
Oczywiście tworzony plik musimy zakończyć znakiem końca pliku – kombinacją Ctrl-D.
Zadanie do wykonania:
Wyświetl zawartość pliku .bash_profile. Połącz (powiel) ten plik, tworząc we własnym
katalogu roboczym inny plik roboczy o nazwie rob_profile.
UWAGA: Nie należy zmieniać ani usuwać plików poprzedzonych znakiem ‘.’.
Polecenia more i less
Polecenia te stanowią rodzaj filtru, wyświetlając zawartość pliku (będącego argumentem
polecenia) na ekranie terminalu w porcjach wielkości strony (typowo 25 wierszy). Polecenie
more ma charakter jednokierunkowy (nie można cofnąć się do poprzednio wyświetlanej
strony), natomiast polecenie less pozwala poruszać się w obu kierunkach. Poruszamy się po
przeglądanym pliku, używając klawiszy PageUp, PageDown (przewinięcie strony) lub
klawiszy oznaczonych strzałkami (tylko o jeden wiersz). Zakończenie polecenia następuje po
naciśnięciu znaku q (quit).
Polecenia mkdir i rmdir
Polecenia służą, odpowiednio, do utworzenia i usunięcia katalogu, którego nazwa jest
argumentem. Używając tzw. znaków specjalnych (wildcards) – patrz punkt dotyczący
substytucji (str. 16) - można usunąć więcej jak jeden katalog.
Zadanie do wykonania:
Utwórz katalog roboczy w katalogu domowym o nazwie: nazwisko_studenta.
Następnie usuń ten katalog i ponownie utwórz.
6
6
Polecenia cp, rm, mv
Polecenie cp służy do kopiowania plików. Sposób użycia, np.:
$ cp plik1 plik2 plik3 /usr/tst/tmp
// skopiuj trzy pliki do katalogu /usr/tst/tmp
Polecenie cp kopiuje zawartości katalogów (grupy plików) do innego katalogu. Polecenie
rm usuwa plik, a także grupy plików. Na przykład
rm *
spowoduje usunięcie wszystkich plików w danym katalogu. Będąc administratorem możemy
w ten sposób usunąć zawartość całego systemu plików!!!
Często stosowane opcje polecenia rm (pozostałe opisane są w podręczniku man):
-f rm działa bez zadawania pytań użytkownikowi
-i
wymusza tryb interaktywny, nawet gdy standardowym wejściem nie jest
terminal
-r
rekursywnie usuwa zawartość katalogów i same katalogi, wyspecyfikowane
w parametrach wywołania
Polecenie mv przenosi plik do innego (wskazanego) katalogu i/lub zmienia jego nazwę, np.:
// przenieś trzy pliki do katalogu /u/tmp
$ mv plik1.txt plik2.txt plik3.txt /u/tmp
Zmiana nazwy pliku (w katalogu domowym):
$ mv plik1.txt nowy.txt
Zadanie do wykonania:
Przenieś powielone pliki do nowego katalogu.
Polecenia zmiany uprawnień chmod, umask, chown, chgrp
W systemie Unix/Linux z każdym plikiem związanych jest szereg atrybutów, które
określają prawa dostępu do pliku. Atrybuty te zapisywane są symbolicznie w postaci
Początkowy ciąg r w x opisuje prawa właściciela pliku, tj. tego, który utworzył plik. I tak
symbol r oznacza prawo do czytania zawartości pliku, symbol w — prawo do zmiany
zawartości pliku lub skasowania pliku, natomiast symbol x oznacza prawo wykonywania
programu zawartego w pliku. Jeśli jakiekolwiek z wymienionych praw dostępu jest
wyłączone, to symbolicznie zapisuje się to w postaci kreski, np. r – x oznacza, że właściciel
s
g
t
r
w
x
r
w
x
r
w
x
uprawnienia
specjalne
uprawnienia dla
właściciela
uprawnienia dla
grupy
uprawnienia dla
pozostałych
użytkowników
7
7
pliku nie ma prawa modyfikacji zawartości pliku ani też nie może go skasować. Kolejna
grupa znaków r w x opisuje prawa dostępu do pliku dla innych użytkowników, należących do
tej samej grupy co właściciel pliku. I wreszcie ostatnia grupa znaków r w x opisuje prawa
dostępu do pliku dla wszystkich innych użytkowników.
Taki sam schemat ochrony stosuje się w odniesieniu do katalogów. W tym przypadku
symbol r oznacza możliwość czytania katalogu, symbol w możliwość zapisania nowego
pliku w katalogu lub utworzenia podkatalogu, zaś symbol x oznacza możliwość dostępu do
katalogu, np. za pomocą polecenia cd.
Zmianę praw dostępu do plików i katalogów można przeprowadzić za pomocą
polecenia chmod. Może tego dokonać jedynie właściciel pliku lub administrator (superuser,
root). Maskę uprawnień podajemy w postaci liczby oktalnej. Sposób określania parametrów
tego polecenia wyjaśnimy na przykładzie.
// pozwól wszystkim użytkownikom wykonywać plik mtest,
// grupie czytać go, a właścicielowi czytać i pisać
$ chmod 751 mtest
Powyższe polecenie ustala prawa dostępu dla pliku mtest. Cyfra z lewej strony określa
prawa dostępu właściciela pliku, cyfra środkowa — prawa dostępu użytkowników należących
do tej samej grupy co właściciel pliku, zaś ostatnia cyfra określa prawa dostępu wszystkich
innych użytkowników. Kodowanie przeprowadzane jest w systemie ósemkowym wg
poniższego schematu.
0
– – –
1
– – x
2
– w –
3
– w x
4
r – –
5
r – x
6
r w –
7
r w x
Uwaga: podczas przygotowywania skryptów należy użyć tego polecenia w stosunku do pliku
zawierającego tekst skryptu, aby można go było później uruchomić.
Polecenie umask pozwala ustawić nową maskę uprawnień nadawaną domyślnie plikom
podczas ich tworzenia.
Ściśle: polecenie umask pozwala określić jakie prawa dostępu nie zostaną przypisane dla
nowo utworzonego pliku. Przykładowo polecenie
umask 444
oznacza, że dla wszystkich nowo utworzonych plików prawo odczytu nie zostanie przyznane.
Wykonanie polecenia umask bez argumentu wyświetla aktualną maskę uprawnień.
Polecenia chown, chgrp służą do zmiany właściciela lub grupy pliku i są używane
najczęściej podczas instalacji bądź rekonfiguracji złożonych aplikacji, np. baz danych.
8
8
Polecenia zarządzania procesami ps, kill
Polecenie ps służy do wyświetlenia listy aktualnych procesów. Typowe opcje to:
-e
wyświetl wszystkie procesy
-f
generuj pełną informację o procesach
-t termilist
wyświetl procesy związane z terminalem termlist
-u uidlist
wyświetl procesy związane z użytkownikiem uidlist
-g gidlist
wyświetl procesy związane z grupą gidlist
Zadanie do wykonania:
Wyświetl listę procesów własnych, a następnie wszystkich z pełnym opisem.
Polecenie kill służy do przesłania sygnału danego typu do wskazanego procesu, np.
// wyślij sygnał 9 do procesu 1132
$ kill -9 1132
Powoduje bezwzględne zakończenie działania procesu o identyfikatorze 1132.
Środowisko powłoki
Powłoka, aby poprawnie pracować, musi mieć określone środowisko. Składa się ono z
podstawowych dwóch elementów:
katalogu aktualnego,
zmiennych powłoki.
Katalog aktualny (inaczej bieżący) to plik, który dla powłoki jest katalogiem odniesienia. Po
rozpoczęciu pracy najczęściej katalogiem bieżącym jest katalog macierzysty (ang. home
directory). Katalog aktualny zmieniamy poleceniem cd, np.
cd /usr/bin
Zmienne powłoki określają poszczególne elementy środowiska. Część zmiennych jest
predefiniowanych, tzn. mają swoją wartość już przy rozpoczęciu pracy. Zmienne powłoki
przechowują wartości tekstowe. Wartości zmiennych można wykorzystywać w funkcjach i
procedurach powłoki, można tworzyć nowe zmienne, można zmieniać ich wartość. Zmienne
powłoki mogą być lokalne lub globalne. Utworzenie nowej zmiennej lub zmiana wartości
odbywa się poleceniem:
<nazwa_zmiennej>=<wartość>
Zauważ, że pomiędzy znakiem = a pozostałymi nie występuje spacja. Spacja jest separatorem
elementów składowych polecenia!
9
9
Tab 1. Zestaw typowych zmiennych powłoki
Nazwa
Wartość
Przykład
HOME
katalog macierzysty
/usr/student
PATH
ścieżka poszukiwań
/bin:/usr/bin:/usr/student/bin:.
TERM
typ terminala
ansi
PS1
pierwszy (główny) znak
zachęty
$
PS2
drugi (pomocniczy) znak
zachęty
>
LOGNAME
nazw
a użytkownika
student
TZ=
nazwa strefy czasowej
GMT-1
nazwa pliku - skrzynki
pocztowej
/usr/mail/michk
Należy bezwzględnie zwrócić uwagę na brak spacji przed i po znaku równości - jeśli byśmy
napisali np. coś takiego
PATH = /bin:/usr/bin
to powłoka zinterpretuje to jako wywołanie programu o nazwie PATH i dwóch parametrach:
= oraz /bin:/usr/bin
Przykłady nadawania wartości:
PATH=/bin:/usr/bin
ala=ma_kota
piec=555
ala=teraz_taki_sobie_tekst
Ale
ala=taki sobie tekst
oznacza tymczasowe nadanie zmiennej ala wartości taki, a następnie wykonanie programu
o nazwie sobie z jednym parametrem – tekst. W ten sposób powłoka umożliwia nadanie
zmiennej wartości tylko na czas wykonania polecenia (w tym przypadku sobie).
W poleceniach odwołujemy się do zmiennych powłoki, poprzedzając ich nazwę znakiem $,
np.:
cd $HOME
spowoduje powrót do katalogu macierzystego.
Wartości poszczególnych zmiennych możemy obejrzeć poprzez polecenie echo, np.:
echo $PATH
wyświetli na ekranie wartość zmiennej PATH.
Wartości wszystkich zmiennych od razu wyświetla polecenie set. Zmienne są wyświetlane
w kolejności alfabetycznej. Często pojawia się problem kolizji nazw zmiennych. Jeśli mamy
zdefiniowaną następującą zmienną:
ala=tekst
to użycie jej w postaci
10
10
echo $alaxyz
spowoduje wyświetlenie tekstu:
tekstxyz
Jeśli dodatkowo zdefiniujemy zmienną:
alaxyz=coś_innego
to poprzednie polecenie echo oczywiście wyświetli teraz wartość zmiennej alaxyz:
coś_innego
Aby uzyskać wartość zmiennej ala, w takiej sytuacji stosuje się nawiasy klamrowe:
echo ${ala}xyz
powoduje wyświetlenie
tekstxyz
Przetwarzanie potokowe na poziomie powłoki
Interpreter poleceń umożliwia automatyczne przekazywanie danych wyjściowych z
jednego programu (procesu) jako danych wejściowych dla innego programu — mechanizm
ten, określany jest jako przetwarzanie potokowe (ten sam termin używany jest w innym
znaczeniu w zagadnieniach architektury procesorów). Przetwarzanie potokowe realizowane
jest za pomocą łączy komunikacyjnych (ang. pipes), które oznacza się symbolem |. Takie
łącze tworzy się poprzez bezpośrednie związanie standardowego strumienia wyjściowego
procesu poprzedzającego ze standardowym strumieniem wejściowym innego, następnego
procesu. Przetwarzanie potokowe w systemie Windows (zapożyczone z systemu Unix) i
Linux uruchamia się w identyczny sposób, np.:
$ oblicz | sortuj
(Linux)
C:\> oblicz | sortuj
(Windows)
W systemie Linux, łącza implementowane są jako bezpośrednia komunikacja między
procesami. Niekiedy używany jest tee (rozgałęźnik T), który kopiuje standardowy strumień
wejściowy do standardowego strumienia wyjściowego, tworząc przy tym dodatkową kopię w
podanym pliku, np.
$ ftp ftp.mv.com | tee rejestracja.txt
Filtry stanowią specyficzną odmianę programów usługowych, które zazwyczaj operują na
tekstach (strumieniach znaków) i przeznaczone są wyodrębniania i przekształcania określonej
informacji. Źródłem i przeznaczeniem strumienia znaków mogą być pliki, inne programy lub
dowolne urządzenia znakowe. Operacje wykonywane przez filtry obejmują najczęściej:
— sortowanie pliku wejściowego,
— usuwanie linii tekstu wg przyjętego kryterium,
— zastępowanie wskazanych łańcuchów znakowych przez inne,
— szyfrowanie i deszyfrowanie.
11
11
Filtry stosowane są szeroko w systemie Linux. W systemie Linux i Windows są dostępne
m.in. filtry sort i more. Przykładowe wywołanie może mieć postać:
$ ls –l | sort
(Linux)
C:\> dir | sort
(Windows)
Filtry pobierają informacje ze standardowego wejścia i po przetworzeniu przesyłają je do
standardowego wyjścia; przekształcanie realizowane jest wg reguły "znak po znaku" lub
"linia po linii".
Logowanie się do systemu
Do zalogowania się w systemie Linux musimy użyć następujących danych:
login: student
password: student
Po uruchomieniu systemu otwieramy okno terminala, wybierając opcje:
Aplikacje → Narzędzia systemowe → Terminal
Następnie należy wykonać kolejno opisane polecenia, używając opcji wskazanych przez
prowadzącego zajęcia.
Zadania do wykonania:
Wykonaj proste ćwiczenia związane z poleceniami systemu, podane na stronach 3,4,5.
Następnie wykonaj poniższe zadania.
Zadanie 1.
a) wyświetl aktualne zmienne powłoki,
b) utwórz nową zmienną, będącą konkatenacją zmiennych HOME i PATH,
c) wyświetl wartość nowej zmiennej.
UWAGA: Nie należy zmieniać ani usuwać zmiennych powłoki $HOME i $PATH.
Zadanie 2.
a) Używając edytora, np. Aplikacje → Akcesoria → edytor tekstu, utwórz
plik w katalogu o nazwie będącej nazwiskiem studenta zawierający, wśród innego
tekstu, frazę np. Ala ma kota, a kot myszke.
b) Skopiuj plik na inny, zmieniając bądź dodając inne fragmenty tekstu. Tekst
wyróżniony powinien jednak pozostać w niezmienionej formie.
c) Powtórz krok podany w pkt. b) kilka razy.
d) Nadaj plikom wydłużenie nazwy .txt.
e) Wykonaj polecenie
grep 'Ala ma kota' *.txt | more
Wykonaj ponownie polecenie, przekazując wynik do dowolnego nowego pliku. Nie
zapomnij poprzedzić nazwy pliku pełną ścieżką dostępu.
12
12
Zadanie 3.
Napisz wiersz polecenia, który wyszukuje w listingu wszystkie pliki należące do danego
użytkownika i zapisuje wynik do pliku.
Zadanie 4.
a) używając polecenia ls, wyświetl zawartość wskazanego przez prowadzącego
katalogu, sortując wg ustalonego kryterium.
b) Powtórz działanie z pkt. a, używając potoku i polecenia sort. Sprawdź dostępne
opcje, używając polecenia man sort | less. Sortowania dokonać wg wskazanej
przez prowadzącego kolumny.
ls –l | sort –t' '
Uwaga:
W powyższym poleceniu występuje opcja –t' '. Oznacza ona, że separatorem
pomiędzy kolumnami będzie spacja. Ponieważ spacja jest standardowym separatorem
elementów polecenia, to aby była ona parametrem opcji, musi być ujęta w cudzysłowy.
13
13
Część B: Podstawy programowania w języku powłoki
Powłoka (ang. shell) jest programem umożliwiającym pracę z systemem Linux. Jej
nazwa wywodzi się z graficznej prezentacji systemu, w której jądro i procesy obsługi wejścia
i wyjścia są otoczone właśnie przez powłokę. Jej funkcją jest odseparowanie użytkownika od
bezpośredniego dostępu do jądra systemu i umożliwienie łatwej i wszechstronnej pracy.
Podstawowym zadaniem powłoki jest przyjmowanie poleceń użytkownika i
uruchamianie stosownych programów. Do dalszych funkcji powłoki należy konstruowanie
parametrów dla poleceń oraz zarządzanie sposobem wykonywania programów – procesów.
Następnym, bardziej skomplikowanym krokiem jest tworzenie funkcji i procedur powłoki
(skryptów) pozwalających na łączenie wielu poleceń w jedno, umożliwiając pisanie całych
programów dla powłoki.
Powłoka jest programem, z którym użytkownik systemu Linux spotyka się na samym
początku. Jej uruchomienie następuje automatycznie, bezpośrednio po zalogowaniu
(zgłoszeniu) użytkownika w systemie. Gdy widzimy na ekranie znak $, oznacza to, że
powłoka jest już uruchomiona i oczekuje na podawanie poleceń.
System Linux oferuje wiele powłok. W czasie zajęć przede wszystkim zostanie
omówiona powłoka standardowa oznaczana skrótem sh i zwana Bourne shell.
Podstawowymi poleceniami są dwa następujące:
: <dowolne parametry>
# komentarz
Pierwsza z nich (dwukropek) to polecenie puste – nic nie robi, zwraca kod błędu 0. Drugie
(hash) to komentarz – tym się różni od poprzedniego, że nie zmienia zmiennej $? - kodu błędu
ostatnio wykonanego procesu.
Normalnie powłoka postępuje w taki sposób, że po uruchomieniu programu czeka na
zakończenie jego wykonania i dopiero wtedy znów wyświetla znak zachęty i oczekuje na
wprowadzenie następnego polecenia. Można jednakże uruchomić program "w tle", to znaczy
powłoka nie będzie czekała na zakończenie jego działania, tylko od razu wyświetli znak
zachęty. Przykład:
$ obliczenia dane.txt &
[2313]
$
Znak & podany na końcu polecenia powoduje jego uruchomienie w tle.
Wykaz zmiennych polecenia powłoki:
Nazwa
Wartość
Przykład
$0
nazwa wykonywanego programu
sh
$1
pierwszy parametr wywołania
ala.txt
$2...$9 następne parametry wywołania
prog.c
$*
wszystkie parametry wywołania
ala.txt prog.c
$@
jw, ale parametry jako osobne łańcuchy znaków
"ala.txt" "prog.c"
$#
liczba parametrów
2
$-
opcje powłoki podane przy wywołaniu
-xv
$?
kod błędu ostatnio wykonanego polecenia
0
$$
numer procesu powłoki
12345
$!
numer procesu ostatnio wykonanego w tle
12560
14
14
Podane niżej wyrażenie jest nazwą pliku o unikalnej nazwie:
/tmp/plik.$$
Przekierowanie wejścia i wyjścia, potoki
Każdemu procesowi na początku jego pracy system udostępnia trzy strumienie:
standardowe wejście - strumień o numerze 0,
standardowe wyjście - strumień o numerze 1,
standardowe wyjście błędu - strumień o numerze 2.
Powłoka uruchamiając każdy proces udostępnia mu swoje standardowe strumienie.
Ponieważ na początku ich rolę pełni terminal (wejście – klawiatura, wyjście – ekran), więc i
programy – procesy uruchamiane przez użytkownika będą miały tak przyporządkowane
strumienie.
Istnieje możliwość zmiany ustawienia strumieni – przekierowanie (ang. redirection).
Wiele programów systemu Unix/Linux to tzw. filtry, czyli czytające tylko ze standardowego
wejścia i piszące tylko na standardowe wyjście. Używając mechanizmu przekierowania
można uzyskać efekt ich pracy na plikach. Przekierowanie wyjścia może odbywać się dwoma
sposobami:
polecenie > nazwa_pliku
polecenie >> nazwa_pliku
Pierwszy sposób powoduje zapisanie do pliku nazwa_pliku całego standardowego
wyjścia z polecenia. Jeśli taki plik istniał, jego poprzednia zawartość zostanie usunięta. Drugi
sposób powoduje dopisanie wyjścia standardowego z polecenia do ew. istniejącej już
zawartości pliku.
Przekierowanie wejścia realizujemy następująco:
polecenie < nazwa_pliku
Proces uruchomiony poleceniem będzie odczytywał dane z pliku nazwa_pliku, a nie z
terminala.
Z pojęciem przekierowania łączy się też mechanizm następujący:
polecenie << słowo
Mechanizm ten nie ma zastosowania w pracy interakcyjnej. Podczas pisania procedur
powłoki (skryptów) można w ten sposób uzyskać efekt odczytu danych przez program z
samego skryptu.
Wszystkie programy systemu Linux swoje komunikaty diagnostyczne wyprowadzają
na standardowe wyjście błędów (standardowo też ekran terminala). W przypadku
przekierowania wyjścia standardowego:
1. Unikamy niepotrzebnych komunikatów diagnostycznych w pliku. Najczęściej jest on
wejściem do następnego programu, dla którego komunikat diagnostyczny jest
bezsensowny,
2. Uzyskujemy na terminalu informację o błędzie. Jeśli program zauważa błąd w danych,
to wyświetla komunikat; gdyby komunikat też był przekierowany do pliku,
użytkownik w ogóle nie zorientowałby się, że zdarzyła się błędna sytuacja.
Jeżeli nie chcemy, aby komunikaty o błędach pojawiały się na ekranie, to możemy
niezależnie przekierować standardowe wyjście błędów. Odbywa się to w sposób:
15
15
polecenie 2> nazwa_pliku
Można też połączyć kilka strumieni w jeden, podając np. że wyjście ze strumienia 5 ma być
połączone z wyjściem strumienia 1 (standardowego wyjścia):
polecenie 5>&1
Przekierowania są ważnym elementem w przypadku wykonywania programów w tle.
Standardowym wejściem takiego programu jest /dev/null, czyli wejście puste, zaś
wyjściem jest terminal. Aby uniknąć pomieszania informacji na ekranie, stosuje się
przekierowanie:
program <dane.txt > wyniki.txt 2 > bledy.txt &
Przykłady:
Typowym poleceniem dla przykładów na przekierowanie jest polecenie cat:
cat plik_1 plik_2 ... plik_n
Gdy nie podamy żadnych parametrów poleceniu cat, to odczyt następuje ze standardowego
wejścia, więc w takim wypadku cat po prostu kopiuje standardowe wejście na standardowe
wyjście. Polecenie
cat prog.c > prog1.c
powoduje przekopiowanie zawartości pliku prog.c do pliku prog1.c. Polecenie
cat <prog.c >prog1.c
daje efekt identyczny. Z kolei polecenie
cat *.txt >wszystkie 2>bledy
kopiuje wszystkie pliki o nazwach kończących się na .txt do pliku wszystkie, zaś
komunikaty o błędach trafiają do pliku bledy. Podane niżej polecenie może służyć do
sprawdzenia czy plik istnieje
cat *.txt > /dev/null
Polecenie
cat < ala.txt > ala.txt
spowoduje wyzerowanie pliku ala.txt ! Dlaczego?
Bardzo często wyjście jednego polecenia jest wejściem następnego, np.
ls /usr/student > /tmp/mkdir
grep abcd < /tmp/mkdir
rm /tmp/mkdir
lub równoważne polecenie z użyciem potoku
ls /usr/student | grep abcd
ls /usr/student | grep abcd | more
Ewentualne przeadresowania wejścia i wyjścia odnoszą się tylko do poszczególnych poleceń,
np.
ls /usr/student | grep abcd 2 > bledy
16
16
powoduje przekierowanie standardowego wyjścia błędu tylko polecenia grep. Można
uzyskać łączne przekierowanie stosując grupowanie poleceń.
Rozwijanie nazw plików i cytowanie
Można używać następujących metaznaków:
*
pasuje do dowolnego tekstu
?
pasuje do dowolnego znaku
[...] pasuje do każdego znaku z wymienionych między nawiasami
[x-y] pasuje do każdego znaku znajdującego się pomiędzy x i y (z nimi włącznie)
[!..] pasuje do każdego znaku z wyjątkiem znaków podanych po wykrzykniku.
Uwaga: Poszczególne formy [] można łączyć ze sobą, np. [a-zA-Z0123456789]
Wyobraźmy sobie strukturę katalogów:
/usr/student/
ala.txt
info.1
prog.c
obliczenia/
dane1.txt
wyniki.txt
rozne/
rozne.1
rozne.2
rozne.3
Katalogiem bieżącym jest /usr/student
Warto zwrócić uwagę, że występująca kropka w nazwach plików nie rozdziela nazwy od
rozszerzenia (jak w Windows), ale jest po prostu elementem nazwy takim samym, jak każdy
inny znak.
Powłoka zawsze dokonuje rozwinięcia w kolejności alfabetycznej.
Metaznak
Wynik
*.1
info.1 (ale nie rozne/rozne.1 !)
*/*
obliczenia/dane1.txt
obliczenia/wyniki.txt rozne/rozne.1
rozne/rozne.2 rozne/rozne.3
[a-k]*
ala.txt info.1
[!abc]*c
prog.c obliczenia rozne
*o*
info.c obliczenia rozne prog.c
*.?
info.1 prog.c
*.??
*.?? (nic nie pasuje)
*.???
ala.txt
*[!.]*
obliczenia rozne
17
17
Polecenie
cat *.?
powoduje, że program cat otrzyma jako pierwszy parametr info.1, jako drugi prog.c,
czyli tak, jakby podać polecenie:
cat info.1 prog.c
Cytowanie znaków (substytucja)
Czasami nie chcemy, aby powłoka rozwijała nazwy plików. Przykładem może być
polecenie find:
find . -name *.txt -print
powoduje wyszukanie i wyświetlenie nazw wszystkich plików pasujących do podanego
wzorca – w tym przypadku *.txt. Przeszukiwane są katalogi: bieżący (oznacza go znak .
(kropka)) i wszystkie podkatalogi. Opcja print powoduje wyświetlenie wyników na
standardowym wyjściu.
Takie podanie polecenia powłoce spowoduje jednak rozwinięcie nazwy pliku i w rezultacie
program find otrzyma następujące parametry:
find . -name ala.txt –print
co całkowicie zmienia znaczenie – teraz znalezione będą tylko pliki o nazwie ala.txt.
Aby zabronić powłoce dokonywania substytucji, stosowane jest cytowanie znaków. Są
dostępne następujące mechanizmy:
poprzedzanie znakiem "\" (backslash). Każdy znak po nim nie jest interpretowany przez
powłokę, a więc można nasze polecenie podać w sposób następujący:
find . -name \*.txt –print
tym znakiem możemy podać programowi wszystkie znaki, włącznie z takimi, które są
interpretowane przez powłokę:
program dane.txt \&
spowoduje przekazanie znaku "&" do programu, a nie wykonanie programu w tle.
poprzez ujęcie tekstu w cudzysłowy, np.
find . -name "*.txt" -print
takie cytowanie powoduje, że nie jest dokonywane rozwinięcie nazw plików w tekście
w cudzysłowach oraz dodatkowo, cały tekst ujęty w cudzysłowy jest traktowany jako
pojedynczy parametr dla polecenia.
grep "ala ma kota" dane.txt
powoduje wyszukanie tekstu ala ma kota w pliku dane.txt.
$ echo "To jest
> wielowierszowy pojedynczy
> parametr dla polecenia
> echo i tak właśnie będzie wyświetlony"
18
18
poprzez ujęcie tekstu w apostrofy:
find . -name ‘*.txt’ -print
od poprzedniego rozwiązania różni się tym, że nie jest dokonywana tutaj żadna
substytucja, także nazw zmiennych.
Zestaw poleceń
nazwa=\*.txt
echo $nazwa
echo ”$nazwa”
echo ‘$nazwa’
spowoduje wyświetlenie kolejno
prog.txt
*.txt
$nazwa
Substytucja poleceń
Powłoka jest w stanie wykonać dane polecenie i wyniki jego działania przedstawić
jako listę parametrów dla innego polecenia. Odbywa się to przez umieszczenie jej wywołania
w znakach akcentu, np.:
rm -i `find . -name *.tmp –print`
Najpierw wykonywane jest polecenie find, podające listę nazw plików odpowiadających
wzorcowi, np.:
./dane.tmp
./info.tmp
./obliczenia/aa.tmp
./obliczenia/bb.tmp
./obliczenia/cc.tmp
Ten wykaz zastępuje polecenie find podane w znakach akcentu i dopiero teraz powłoka
wykonuje polecenie rm:
rm -i ./dane.tmp ./info.tmp ./obliczenia/aa.tmp
./obliczenia/bb.tmp ./obliczenia/cc.tmp
Ten mechanizm jest źródłem dużych możliwości w programowaniu powłoki.
Grupowanie poleceń
Polecenia powłoki mogą być zbierane w grupy dwojakiego rodzaju:
poprzez ujęcie listy poleceń w nawiasy klamrowe {}
poprzez ujęcie listy poleceń w nawiasy ()
19
19
Polecenia w liście rozdzielamy średnikami lub znakami nowej linii; w przypadku nawiasów
klamrowych należy podać też średnik po ostatniej poleceniu.
Ujęcie listy poleceń w nawiasy klamrowe służyć może wspólnemu przekierowaniu
wejścia / wyjścia, np.
{ ls /usr/student | grep abcd ; } 2>bledy
{ cat naglowek.txt; ls -l | grep abcd ; } >info.1
Inne zastosowania grupowania w nawiasy klamrowe to wszystkie takie sytuacje, w
których powłoka wymaga jednego polecenia, a potrzeba wykonać kilka.
Ujęcie poleceń w nawiasy powoduje uruchomienie nowej powłoki (mówimy:
podpowłoki) i wykonanie poleceń przez tę podpowłokę. Taki mechanizm stosuje się, gdy
użytkownik nie chce zmieniać środowiska powłoki.
Przykładowo, katalog bieżący należy do środowiska, więc polecenia:
cd / ; ls -l
spowodują wyświetlenie zawartości katalogu głównego; po czym bieżącym katalogiem
pozostanie nadal katalog główny. Użycie nawiasów:
( cd / ; ls -l )
powoduje taki sam efekt, ale po zakończeniu działania tych poleceń katalog bieżący
pozostanie bez zmian, gdyż zmienił się tylko w podpowłoce, która już zakończyła działanie.
Innym zastosowaniem nawiasów może być wykonanie ciągu poleceń w tle, przy czym
wszystkie nie wykonują się niezależnie, ale jedno po drugim:
( cd obliczenia ; oblicz <dane.txt >wyniki.txt
write $LOGNAME "koniec obliczeń") &
Wykonanie względne || i &&
Wykonanie jednego polecenia można uzależnić od efektów działania innego
polecenia. Temu służą dwa operatory: || oraz &&.
Operator || łączący dwa polecenia oznacza, że drugie z nich będzie wykonane tylko
wtedy, gdy wykonanie pierwszego zakończy się błędem. Operator && działa przeciwnie –
drugie polecenie wykonuje się, gdy pierwsze nie kończy się błędem.
Kod błędu ostatnio wykonanego programu możemy zawsze badać analizując zmienną
powłoki $?; innym sposobem jest opisywana właśnie konstrukcja:
grep abcd > wynik.txt < dane.txt || echo nie znaleziono!!!
lub też
grep abcd > wynik.txt < dane.txt && echo znaleziono!!!
20
20
Oba te operatory można traktować jako skrócone wersje instrukcji if.
Polecenia wewnętrzne
nazwa_pliku
powoduje wykonanie poleceń zawartych w podanym pliku. Należy
odróżnić takie wywołanie od skryptu powłoki, który powoduje
utworzenie podpowłoki.
break n
wyjście z pętli for, while lub until. Parametr n oznacza
zagłębienie pętli, domyślnie wynosi 1.
continue n
rozpoczęcie wykonywania pętli for, while lub until od początku.
Parametr n oznacza zagłębienie pętli, domyślnie wynosi 1.
cd katalog
zmiana katalogu bieżącego. Takie polecenie musi być wewnętrzne,
gdyż w przeciwnym wypadku nie dawałoby żadnego efektu –
środowisko powłoki nie ulega zmianie z powodu wykonywania
innych procesów!
eval ...
potraktowanie argumentów jak standardowego wejścia powłoki. np.
program tset podaje na wyjściu tekst "TERM=ansi". Zastosowanie
eval
pozwala zdefiniować zmienną TERM:
eval `tset`
powoduje definicję zmiennej TERM na wartość "ansi"
exec ...
powoduje wykonanie podanego polecenia zamiast powłoki – po jej
zakończeniu powłoka już nie istnieje i nie zgłasza się sygnałem
zachęty (gdy jest to powłoka główna, użytkownik zostaje
"wylogowany" – wyrejestrowany z pracy w systemie).
exit n
zakończenie działania powłoki. Parametr podaje kod błędu, domyślnie
0.
export zmienna
nadaje globalny zasięg zmiennej. Taka zmienna jest dziedziczona
przez podpowłoki i inne procesy potomne. Samo słowo export, bez
parametrów wyświetla wykaz zmiennych eksportowanych przez
powłokę.
read zmienna
odczytanie jednego wiersza z terminala i wpisanie go jako wartości
podanej zmiennej (tu zmienną jest łańcuch znaków). To polecenie
umożliwia pisanie interakcyjnych skryptów i funkcji.
return n
zakończenie działania funkcji powłoki. Parametr podaje kod błędu,
domyślnie 0.
set
wyświetla zmienne powłoki.
set -fntvx
ustawia opcje powłoki (można to robić też przy wywołaniu powłoki,
patrz dalszy rozdział.
set parametry...
ustawia parametry powłoki, dostępne przez $1, $2 itd.
shift n
przesunięcie parametrów. Parametr drugi staje się $1, trzeci $2 itd.
Parametr pierwszy jest tracony. Polecenie użyteczne, gdy parametrów
21
21
jest więcej niż dziewięć. Można ew. przesunąć o więcej niż 1, podając
stosowne n.
trap
ustawianie odpowiedzi powłoki na sygnały.
type nazwa...
podaje, jak dana nazwa (nazwy) byłaby zinterpretowana jako
polecenie (wewnętrzna, funkcja, skrypt, program...)
Instrukcje strukturalne (if, case, for, while, until)
Jak wspomniano na wstępie, powłoka oferuje mechanizmy budowy funkcji i procedur
w celu programowania powłoki. W takim przypadku nieodzowne stają się instrukcje sterujące
przepływem programu, ustalające kolejność wykonywanych działań. Powłoka posiada takie
mechanizmy.
Instrukcja if
Syntaktyka:
if <polecenie>
then <lista_poleceń_1>
else <lista_poleceń_2>
fi
Powłoka wykonuje polecenie. Jeśli kod błędu wynosi 0, to wykonywana jest
lista_poleceń_1; w przeciwnym wypadku lista_poleceń_2. Część else jest
opcjonalna i nie musi występować.
Przykład:
if test -f temp.txt
then rm temp.txt
fi
Uwaga: Wszystkie te polecenia można zapisać w jednym wierszu, rozdzielając średnikami
kolejne polecenia:
if test -f temp.txt; then rm temp.txt; fi
Średniki są tu niezbędne – inaczej powłoka nie wiedziałaby, gdzie kończy się jedno polecenie
i zaczyna drugie.
W przypadku wykonywania zagnieżdżonych instrukcji if:
if <polecenie_1>
then <lista_poleceń_1>
else if <polecenie_2>
then <lista_poleceń_2>
else if <polecenie_3>
then <lista_poleceń_3>
else <lista_poleceń_4>
22
22
fi
fi
fi
można używać konstrukcji łączącej else if w jedno elif:
if <polecenie_1>
then <lista_poleceń_1>
elif <polecenie_2>
then <lista_poleceń_2>
elif <polecenie_3>
then <lista_poleceń_3>
else <lista_poleceń_4>
fi
Można teraz wrócić do poprzedniego rozdziału, z operatorami || i &&. Jak widać oba zapisy
są równoważne:
polecenie_1 && polecenie_2
if <polecenie_1>
then <polecenie_2>
fi
polecenie_1 || polecenie_2
if <polecenie_1>
then
else <polecenie_2>
fi
Instrukcja case
Syntaktyka:
case <słowo> in
<wzór_1> ) <lista_poleceń_1> ;;
...
<wzór_n> ) <lista_poleceń_n> ;;
esac
W przypadku wykonywania tej samej listy poleceń dla kilku wzorów, można podać:
<wzor_1>|<wzor_2>|...|<wzor_i> )<lista_poleceń_i> ;;
Łańcuch <słowo> jest porównywany po kolei z podanymi wzorami. W przypadku
znalezienia zgodności, wykonywana jest odpowiednia lista poleceń. Zgodność jest rozumiana
identycznie jak przy rozwijaniu nazw plików z użyciem metaznaków, więc aby uzyskać
wykonanie listy "otherwise" (gdy żaden wzór nie pasuje), należy na końcu podać wzór w
postaci gwiazdki, jak w przykładzie.
Przykład:
# skrypt o nazwie append
case $# in
23
23
1)
cat >> $1 ;;
2)
cat <$1 >>$2 ;;
*)
echo 'składnia: append [z] do' ;;
esac
Uwaga: po wykonaniu stosownej listy poleceń nie są wykonywane kolejne listy, jak to ma
miejsce w języku C – powłoka zachowuje się podobnie do języka Pascal.
Instrukcja for
Składnia:
for <nazwa>
do
<lista_poleceń>
done
for <nazwa> in <lista_słów>
do
<lista_poleceń>
done
Pierwsza z tych form powoduje, że lista poleceń zostanie wykonana tyle razy, ile
parametrów przekazano do powłoki lub skryptu. Zmienna po podanej nazwie nazwa będzie
przyjmowała po kolei wartości tych parametrów.
Przykład:
for i
do
echo $i
done
wyświetli wykaz wszystkich parametrów, każdy w osobnym wierszu.
Druga forma powoduje wykonanie listy poleceń dla każdego słowa w podanej liście
słów. Typowym przykładem jest wykonanie jakiejś akcji dla podanych plików:
for i in *.txt
do
if grep ”Plik do skasowania” <$i
then rm $i
fi
done
powoduje usunięcie takich plików, które mają nazwy zakończone na .txt i zawierają napis
Plik do skasowania
. Szczególnie wykorzystując substytucje poleceń można tworzyć
ciekawe konstrukcje, np. ten sam problem, ale wykonany dla wszystkich plików, nie tylko w
bieżącym katalogu ale i w podkatalogach będzie rozwiązany następująco:
24
24
for i in `find . -name "*.txt" -print`
do
if grep "Plik do skasowania" <$i
then rm $i
fi
done
Instrukcja while
Syntaktyka:
while <lista_poleceń_1>
do <lista_poleceń_2>
done
Wykonanie tej instrukcji polega na wielokrotnym wykonywaniu pierwszej listy poleceń; w
przypadku, gdy kod błędu ostatniego z poleceń w liście wynosi 0, wykonywana jest druga
lista poleceń i proces się powtarza; kod błędu niezerowy oznacza zakończenie tej pętli.
Przykład:
while
echo -n "Czy wykonać (t/n) "
read x
case $ x in
[tTnN]* ) false ;;
* ) true ;;
esac
do
echo Podaj "t" lub "n"
done
Instrukcja until
Syntaktyka:
until <lista_poleceń_1>
do <lista_poleceń_2>
done
Wykonanie tej instrukcji polega na wielokrotnym wykonywaniu pierwszej listy
poleceń; w przypadku, gdy kod błędu ostatniego z poleceń w liście jest niezerowy,
wykonywana jest druga lista poleceń i proces się powtarza; zerowy kod błędu oznacza
zakończenie tej pętli.
25
25
Funkcje powłoki
Powłoka umożliwia definicje funkcji. Funkcje te mogą być później wywoływane.
Definicja funkcji wygląda następująco:
nazwa() polecenie
W ten sposób tworzymy funkcję o nazwie nazwa i treści polecenie. Wywołując funkcję
możemy podawać parametry:
komunikat() { echo błędn$1 $2 w $3 ; }
komunikat y znak pliku
błędny znak w pliku
komunikat a linia danych
błędna linia w danych
Przykład:
gettn() {
while
echo -n $*
echo -n " (t/n) ? "
do
read yn reszta
case $yn in
[yY] ) return 0 ;;
[nN] ) return 1 ;;
* ) echo "Proszę podać T lub N" >&2 ;;
esac
done ;
}
Wykorzystanie:
gettn "Czy skasować plik" || break ;
Inny przykład:
ccd () { cd $1 ; PS1="`pwd` $" ;}
Powoduje wyświetlanie bieżącego katalogu jako znaku zachęty powłoki. Każdorazowe
wykonywanie ccd zamiast cd umożliwia bieżące zmiany znaku zachęty:
$ ccd /usr/bin
/usr/bin $
26
26
Procedury powłoki, podpowłoka
Procedury powłoki (skrypty) to zapisane w oddzielnych plikach polecenia powłoki.
Wykonujemy je podając polecenie
sh nazwa_pliku
lub krócej
nazwa_pliku
gdy plik ma ustawiony atrybut wykonywalności x.
Takie wywołanie powoduje uruchomienie nowej powłoki (podpowłoki), która
wykonuje polecenia zapisane w skrypcie. Podpowłoka dziedziczy środowisko, a więc katalog
bieżący i wszystkie zmienne globalne powłoki.
Sygnały
Polecenie wewnętrzne trap umożliwia ustawienie reakcji niestandardowej powłoki
na przychodzące do niej sygnały. Składnia tego polecenia jest następująca:
trap <polecenie> n
i oznacza, że po wystąpieniu sygnału o numerze n zostanie wykonane polecenie. Pusty
łańcuch oznacza, że dany sygnał ma być zignorowany:
Standardową reakcją powłoki na sygnał INTERRUPT (klawisz <Del>) jest ignorowanie go.
Można jednakże poleceniem
trap exit 2
spowodować, że sygnał ten spowoduje przerwanie pracy powłoki i "wylogowanie"
użytkownika.
Opcje wykonania powłoki
Podczas uruchamiania powłoki oraz w trakcie jej działania możemy podawać opcje.
Uruchamiając podajemy je jak każdemu programowi, np:
sh -xv
W trakcie działania powłoki poleceniem wbudowanym set:
set -xv
Aby opcję wyłączyć, należy podać po niej znak +:
set -x+
Powłoka ma następujące opcje:
-c tekst powoduje wykonanie pojedynczego polecenia, podanego za opcją. Nie można
jej ustawić poleceniem set.
-r
wywołanie powłoki okrojonej
-s
polecenia są czytane z wejścia standardowego
-e
zakończenie powłoki, jeśli wystąpi błąd przy wykonaniu polecenia
-f
zablokowanie rozwijania nazw plików
27
27
-n
polecenia są tylko czytane, nie są wykonywane. Służy do uruchamiania
skryptów
-u
traktowanie jako błędu użycia niezdefiniowanej zmiennej. Normalnie wstawiany
jest łańcuch pusty
-v
wyświetlanie wierszy poleceń po ich przeczytaniu
-x
wyświetlenie wierszy poleceń przed wykonaniem (opcje -xv umożliwiają
obejrzenie, jak działa substytucja)
-
znak - jest argumentem, nie opcją.
Ćwiczenia
Zadanie 1.
Skopiuj następujący fragment skryptu:
if test $# -gt 3
then
echo ‘za duzo parametrow’
exit 1
else
if test –f $1
then
echo “$1 jest plikiem “
plik=$1
echo „nazwa pliku to $plik”
exit 2
else
if test –d $1
then
echo “ $1 jest katalogiem”
katalog=$1
exit 3
fi
fi
fi
Zauważmy, że każda otwarta instrukcja if musi mieć swój odpowiednik zakończenia w
postaci „fi”.
Następnie zmień uprawnienia przy użyciu polecenia chmod, nadając prawa do wykonania
skryptu. Wywołaj kolejno skrypt z jednym, dwoma, trzema i 4 parametrami. Zapisz rezultaty.
28
28
Zadanie 2
Utwórz nowy skrypt:
if test $# -eq 1
then
{
if test –d $1
then
{
echo "podany argument jest katalogiem"
echo "katalog roboczy to $1"
katalog=$1
}
else
{
echo "to nie katalog – blad!!!!"
exit
}
fi
}
else
if test $# -gt 1
then
{
echo "za duzo argumentow"
exit
}
else
{
katalog=`pwd`
echo "katalog roboczy to $katalog"
}
fi
fi
Pytanie:
Co oznacza konstrukcja:
katalog=`pwd`
Zmień uprawnienia i wytestuj, używając odpowiednich argumentów wywołania.