Forum www.ispwsznysa.fora.pl Strona Główna www.ispwsznysa.fora.pl
Informatyka Stosowania PWSZ NYSA
 
 FAQFAQ   SzukajSzukaj   UżytkownicyUżytkownicy   GrupyGrupy   GalerieGalerie   RejestracjaRejestracja 
 ProfilProfil   Zaloguj się, by sprawdzić wiadomościZaloguj się, by sprawdzić wiadomości   ZalogujZaloguj 

Materiały w formie elektronicznej - wklejam na forum :-)

 
Napisz nowy temat   Odpowiedz do tematu    Forum www.ispwsznysa.fora.pl Strona Główna -> Systemy operacyjne I
Zobacz poprzedni temat :: Zobacz następny temat  
Autor Wiadomość
KOSA
Bywalec



Dołączył: 09 Gru 2007
Posty: 40
Przeczytał: 0 tematów


PostWysłany: Nie 14:08, 15 Cze 2008    Temat postu: Materiały w formie elektronicznej - wklejam na forum :-)

Uruchamianie skryptów
Skrypty uruchamiamy na kilka sposobów:

• poprzez wpisanie:
bash skrypt

• nadając plikowi prawo wykonywania:
chmod +x skrypt
a następnie uruchomienie:
./skrypt

• najprościej:
skrypt
Aby tak uczynić należy spełnić jeden z dwóch warunków:
Skopiować plik do katalogu ~./bin lub do /usr/bin albo zmodyfikować zmienną $PATH.

Wyświetlanie tekstu

#!/bin/bash
echo "ten tekst zostanie wyswietlony"
echo "w dwoch wierszach"

Aby oba teksty zostały wyświetlone w jednej linii trzeba dopisać parametr-n do polecenia echo. Wtedy nie jest dodawany znak nowego wiersza:

#!/bin/bash
echo -n "To jest tylko"
echo "jedna linijka tekstu"

Zeby spowodować przejście do nowego wiersza, należy użyć znaku \n oraz parametru -e dla polecenia echo .

#!/bin/bash
echo -e "To jest pierwszy wiersz \n a to drugi"

Znaki specjalne:





Przekierowania (redirekcja)
Wyniki działań większości poleceń wysyłane są bezpośrednio na ekran monitora. Jednak często zdarza się że chcielibyśmy zapisać je w postaci pliku. Tutaj z pomocą przychodzą przekierowania strumieni.

Przykładowo chcąc zapisać listę plików wyświetlaną poleceniem ls do pliku zrobilibyśmy następująco:

ls > plik

Jeśli taki plik już istniał zostanie nadpisany, czyli stara zawartość zginie i zostanie zastąpiona nową. Jeżeli nie było pliku o tej nazwie zostanie on utworzony.

Dopisanie do pliku bez usuwania starej zawartości odbywa się za pomocą dwóch strzałek:

ls >> plik

Często zdarza się że chcemy zapisać komunikaty błędów. W tym wypadku musimy odebrać dane ze strumienia błędów. Robimy to pisząc 2> jako znak przekierowania:

sl 2> plik

Ponieważ polecenia sl nie ma w systemie - do pliku zostanie zapisany komunikat błędu

Jeżeli chcemy szybko zapisać jakiś wyraz do pliku, wcale nie musimy otwierać żadnego edytora tekstu. Wystarczy zrobić przekierowanie polecenia echo:


echo "Jakiś napis" > plik

A co w przypadku gdy jednocześnie chcemy wysłać dane na ekran oraz do pliku? Tu z pomocą przychodzi nam programik o nazwie tee, który wstawiony w potok za naszym poleceniem wysyła dane jednocześnie na ekran i na twardy dysk. Robi się to następująco:

ls | tee plik

Proste prawda?

Teraz pokażę jak połączyć wiele plików w jeden za pomocą polecenia cat i oczywiście przekierowań.
Polecenie cat wyświetla zawartość pliku (lub kilku).

cat plik1 plik2 > plik3

W ten prosty sposób dane z obydwu plików znalazły się w postaci jednego dużego pliku.

Co więcej - możemy nawet dokonać podobnej czynności z wszystkimi plikami w bieżącym katalogu stosując zamiast nazwy pliku gwiazdkę:

cat * > wszystkie

Istnieje również mechanizm wczytania danych za pomocą odwrotnego przekierowania. Bliżej poznamy go w następnych rozdziałach. Teraz dam tylkko krótki przykład jak można za jego pomocą pobrać tekst z pliku i wysłać do pocztą elektroniczną:

mail [link widoczny dla zalogowanych] < plik_z_wiadomoscia

Dla uściślenia dodam jak nazywają sie kierunki strumieni danych:

stdin - wejście
stdout - wyjście podstawowe
stderr - wyjście diagnostyczne

Aliasy
Alias to po prostu druga nazwa dla danego polecenia.

Jeśli napiszemy:

alias ll="ls -l"

lub

alias ll='ls -l'

będziemy mogli używać zamiast ls -l polecenie ll , które jest znacznie krótsze.

Uwaga: alias ten zniknie po wylogowaniu!

Aby zachować alias należy go dopisać do któregoś ze skryptów startowych np.:

~/.bashrc

lub

/etc/profile

W tym przypadku alias będzie dostępny dla wszystkich użytkowników.


Można to zrobić w ten sposób:

echo "alias ll=\"ls -l\"" >> ~./bashrc


Listę dostępnych aliasów wyświetlamy poleceniem: alias .

Często używane aliasy:

alias vi='vim'
alias md='mkdir'
alias sl='ls'


Polecenie unalias usuwa alias z pamięci.

Przeszukiwanie plików
Program grep przeszukuje plik i wyświetla linie pasujące do wzorca (czyli linie które zawierają szukane słowo).

składnia:

grep szukane_slowo plik

# wiersze zawierające słowo "Linux" w pliku "konfiguracja":

grep Linux konfiguracja

# wiersze ze słowem mariusz w pliku /etc/passwd

grep mariusz /etc/passwd

# wiersze ze słowem Linux we wszystkich plikach *.txt, *.htm i *.html

grep Linux *.{txt,htm?}

Krótki skrypt proszący o nazwę szukanego słowa oraz pliku tekstowego do przeszukania:

#!/bin/bash

echo -n "Szukane slowo: "
read slowo
echo -n "Plik: "
read plik

grep "$slowo" "$plik"
Polecenie

ls | grep ja

wyświetli wszystkie pliki których nazwa zawiera łańcuch ja np. ja, janek, aleja itp.


Gdy chcemy wyświetlić liki do któryh wszyscy mają dowolny dostęp:
ls -l | grep rwxrwxrwx

Wyrażenie:

grep Anna *

Będzie szukać wyrazu Anna we wszystkich plikach bieżącego katalogu

Uzyteczne opcje:

-i - nie zwraca uwagi na wielkość liter

-l - wypisuje tylko nazwy plików

-c - wyświetla tylko numery linii

-w - wyszukuje konkretne słowo tzn. jeśli zażyczymy sobie ciąg 'ma' to zwróci tylko te wiersze w których wystąpił dwuliterowy wyraz 'ma' a nie np. 'mama'

-r - przeszukuje katalog rekursywnie tzn. zagłębia się w strukturę katalogów szukając wyrażenia również w podkatalogach

-C , -C 1, lub -1 - wypisuje określoną ilość linii (domyślnie 2) kontekstu na wyjściu

-E -interpretuje wzorzec jako rozszerzone wyrażenie regularne

-e-używa wzoraca jako wzorac (użyteczne dla ochronienia wzorów zaczynających się od -)

-v -wybiera linie nie pasujące

-x -wybiera tylko te dopasowania które pasują do całej linii
Grep a cytowanie
grep "$HOME" *

podstawia za wyrażenie wartość zmiennej oznaczającej katalog domowy a więc działa tak samo jakbyśmy napisali:

grep "/home/mariusz" *

Gdyby chodziło nam o napis $HOME należy zastosować pojedyńcze cudzysłowy:

grep '$HOME' *
Wyrażenia regularne a grep
Wyrażenia regularne ulatwiaja nam szukanie łańcuchów (wyrazów) w plikach lub w wynikach poleceń wyrzucanych przez konsolę.

Kropka . dopasowuje dowolny pojedynczy znak czyli chcemy wypisac:

- wyrazy trzyliterowe w pliku:

grep ... plik.txt

- trzyliterowe wyrazy które koncza sie końcówką la

grep .la plik.txt

- pięcioliterowe wyrazy mające na trzecim miejscu m a na pozostalych miejscach dowolne znaki

grep ..m.. plik.txt
Jeśli naprawdę chodziłoby nam o wyszukanie kropki np wiersza zawierającego nazwę obraz.gif to znak kropki trzeba "zamaskować" czyli postawić przed nim znak prawego ukośnika:

grep 'obraz\.gif' plik
Znak ^ dopasowuje występujące przed nim wyrażenie do początku wiersza.
- wyrazy rozpoczynajace sie na literę M

grep ^M plik

- wyrazy rozpoczynające się na Mar

grep ^Mar plik

wypisze: Marta Mariusz Marian martenowski
Znak $ działa dokładnie odwrotnie czyli dopasowuje wyrażenie do końca wiersza (piszemy go za wyrażeniem):
- wyrazy kończące się na -la

grep la$ plik

wypisze: ala ela ola krasnala itp.
Wyrażenie w nawiasach kwadratowych [] dopasowuje jeden dowolny znak znajdujący się między nawiasami np.:
- dopasowanie wyrazow ala ola ela

grep [alo]la plik

- dopasowanie wyrazow kot, kat

k[oa]t

Dzieki nawiasom możemy dopasowywać całe zakresy znaków. Przypuśćmy że chcielibyśmy wyświetlić wyrazy zawierające na drugim miejscu dowolną literę:

Zgodnie z tym co poznaliśmy do tej pory napisalibyśmy

a[abcdefghijklmnoprstuwxyz]la

Okazuje się że można zrobić to o wiele prościej - ciąg zawierający wszystkie wyrazy zastąpić takim: [a-z]

a[a-z]la

Oczywiście nie musimy wyszukiwać całego przedziału: można napisać po prostu [a-d]
Tutaj nadmienie jeszcze że aby wypisać również znaki zawierające wielkie litery należy napisać:

[A-Za_z]

W taki sam prosty sposób możemy postąpić z liczbami:

zamiast pisać [0123456789] wystarczy:

[0-9]

Ważna ciekawostka:

Operator [^ ] dopasowuje dowolny znak który nie znajduje się w nawiasach.

Jeżeli chcemy wypisać wszystkie znaki NIE zawierające znaku z tego przedziału dodajemy W NAWIASIE znak ^.

auto_[^4-6]

wyszuka:

auto_1 auto_2 auto_3

ale auto_4 czy auto_5 juz nie.

Wszystkie znaki które nie są cyframi:

[^0-9]

Pamiętajmy że znak ^ służy też do wyszukania wyrażeń znajdujących się na początku łańcucha znaków, jednak wtedy nie znajduje się w nawiasach.
Gwiazdka * oznacza że poprzedzający element będzie dopasowany 0 lub dowolną ilość razy:
An*a

dopasuje wyrazy Ana Anna lub Annnnnna

Jak widać gwiadka ma w wyrażeniach regularnych inne znaczenie niż przy generowaniu nazw plików.

Wyrażenie kropka gwiadka oznacza dowolny ciąg znaków:

.*

dopasuje dowolną ilość znaków obojętnie jakich np wyrażenie:

.*r

dopasuje zarówno wyraz monitor jak i komputer
Nawiasy zwykłe określają zgrupowany ciąg znaków który staje się wyrażeniem regularnym. Chodzi o to że gdy napiszemy wyrażenie:
auta*

to może ono oznaczać auta autaaa itp. a gdy dodamy nawiasy:

(aut)*

to teraz zamiasy gwiazdki pojawi się już nie jedna litera tylko całe wyrażenie z nawiasu np.:

autaut autautaut itp.
Plus (+) znacza że poprzedzający element będzie dopasowany jeden lub więcej razy.
{n} Poprzedzający element pasuje dokładnie n razy.
{n,} Poprzedzający element pasuje n lub więcej razy.

{,m} Poprzedzający element jest opcjonalny i pasuje co najwyżej m razy.

{n,m} Poprzedzający element pasuje co najmniej n razy, ale nie więcej niż m razy.
Znak zapytania (?) oznacza że poprzedzający element jest opcjonalny i występuje najwyżej raz.
grep 'stacja/?' plik

dopasuje wyrazy stacj stacja ale juz np. stacjaa nie da rady.

grep 'Jan/(ek/)/?' plik

dopasuje Jan lub Janek.
Przy wybieraniu wierszy można używać kilku wyrażeń z których musi być spełnione chociaż jedno żeby zwróciło wyniki. Używamy do tego operatora OR (LUB)
grep -E "^c|^d" /etc/termcap

Wybierze wiersze zaczynające się znakiem c lub d.

Polecenie

grep "^c\|^d" /etc/termcap

da dokładnie ten sam wynik jednak znak OR czyli | trzeba zamaskować lewym ukośnikiem.

Maskowanie znaków

Przy używaniu grepa trzeba maskować następujące znaki: + | { } ( ) ?
Nie musimy tego robić gdy użyjemy opcji -E.

Zmienne
Zmienna przechowuje jakąś wartość. Odwołujemy się do niej (odczytujemy ją) pisząc znak $ bezpośrednio przed nazwą zmiennej.

#!/bin/bash
zdanie="Witaj swiecie !!!"
echo $zdanie

Wartości zmiennych można pobrać bezpośrednio od użytkownika:

#!/bin/bash
echo -n "Podaj imię: "
read imie
echo -n "Wiek: "
read wiek
echo "Twoje imię $imie i masz $wiek lat"
echo "Za 5 lat będziesz mieć $[ wiek+5 ] lat"

W ostatnim wierszu można zaobserwować dodawanie liczby 5 do wartości zmiennej. Inne przykłady działań na liczbach przedstawiam poniżej.

a=1
a=$[a+1] # 2
a=$((a+1)) # 2
let "a=a+1" # 2
let "a+=1" # 2

a=`expr $a + 1`
Najprostszy kalkulator


#!/bin/bash
echo
echo -n "Podaj dwie liczby oddzielone spacją: "
read a b

dodawanie=$[ a+b ]
odejmowanie=$[ a-b ]
mnozenie=$[ a*b ]
dzielenie_calkowite=$[ a/b ]

echo "Podane liczby: $a, $b"
echo
echo "Wynik dodawania: $dodawanie"
echo "Wynik odejmowania: $odejmowanie"
echo "Wynik mnozenia: $mnozenie"
echo "Wynik dzielenia calkowitego: $dzielenie_calkowite"


Zapis: dodawanie=$a+$b nie zadziała prawidłowo, tzn nie doda wartości zmiennych i tym samym nie przypisze wyniku zmienej $dodawanie.
Teraz pokażę że zapisy: echo $zmienna i echo "$zmienna" mogą dawać różne rezultaty:

#!/bin/bash

napis="Pisanie skryptow nie jest trudne"

echo $napis # Pisanie skryptow nie jest trudne
echo "$napis" # Pisanie skryptow nie jest trudne

Zapis zmiennej tekstowej bez cudzysłowu usuwa nadwymiarowe odstępy.
Aby zmienna była widoczna w innych powłokach należy ją wyeksportować:

export zdanie

Usuwanie zmiennej z pamieci:

unset zdanie
Zmienne systemowe
W Linuksie istnieje wiele wbudowanych zmiennych. Aktualną ich liste wyświetlamy poleceniami set oraz printenv. Można ich używać następująco:

#!/bin/bash
echo "Witaj $USER, Twoj katalog domowy to $HOME, nazwa i typ tego komputera to $HOSTNAME $HOSTTYPE, znajdujesz sie w katalogu $PWD"

Przykładowe wyniki mogą być następujące

Witaj mariusz, Twoj katalog domowy to /home/mariusz, nazwa i typ tego komputera to unix i386, znajdujesz sie w katalogu /tmp.
Warunki
W języku Shell, tak jak i w wielu innych językach programowania, stosuje się tzw. wyrażenia warunkowe które pozwalaja sterowac działaniem programu.
test
Najkrócej warunek można zapisać w ten sposób

[ $a -eq $b ] && echo "a jest równe b" || echo "Zmienne się różnią"

Czyli: jeśli $a jest równe $b wyświetl komunikat "a jest równe b", w przeciwnym wypadku wyświetl zdanie "Zmienne się różnią".

Wyrażenie w nawiasach kwadratowych jest to warunek testujący używający programu test. Test zwraca kod zakończenia równy 0 gdy warunek został spełniony, w innym przypadku kod zakończenia wynosi 1. Lista dostępnych warunków znajduje się na dole strony oraz w man test.
if-then-fi
if warunek_jest_spelniony
then
polecenie
fi

Wyrażenie to czytamy następująco: Jeżeli warunek jest spełniony wykonaj polecenie.

Skrypt sprawdza czy istnieje plik o nazwie moj_plik
oraz informuje nas, jesli jest to prawdą


#!/bin/bash
if [ -e moj_plik ]
then
echo "Masz plik moj_plik"
fi


Bardzo ważne: nawiasy muszą być odzielone spacją, inaczej nie będzie działać.

-e oznacza - wyrażenie jest prawdziwe, gdy plik o nazwie moj_plik istnieje (exist)

Gdybyśmy chcieli sprawdzić istnienie pliku w swoim katalogu domowym, napisalibyśmy:

if [ -e ~/moj_plik ]
if-then-else-fi
Wyrażenie czytamy następująco: Jeżeli warunek jest spełniony wykonaj polecenie1, jeśli nie jest - wykonaj polecenie2.


if warunek_spelniony
then
polecenie1
else
polecenie2
fi

Skrypt sprawdza czy istnieje plik o nazwie moj_plik
oraz generuje odpowiedni komunikat


#!/bin/bash
if [ -e moj_plik ]
then
echo "Masz plik moj_plik"
else
echo "Nie masz pliku moj_plik"
fi
if-then-elif-else-fi
Tego wyrażenia używamy gdy potrzeba sprawdzić kilka warunków, jednak chodzi nam tylko o spełnienie tylko jednego z nich.

Wyrażenie sprawdza po kolei, który warunek jest spełniony, jeśli taki znajdzie wykona polecenie mu przyporządkowane. Jeśli nie będzie spełniony żaden z warunków, wykonane zostanie polecenie widoczne po instrukcji else.


if warunek1
then
polecenie1
elif warunek2
polecenie2
elif warunek3
polecenie3
else
polecenie4
fi

Uwaga: jeśli dodamy znaku wykrzyknika przed warunkiem, to polecenie wykona się tylko wtedy, gdy warunek NIE jest spełniony, np instrukcja

if [ ! -e plik ]
then
polecenie
fi

spowoduje że polecenie wykona się tylko wtedy, gdy plik NIE istnieje.


Skrypt sprawdza czy plik o nazwie moj_plik jest zwykłym plikiem,
katalogiem, czy dowiązaniem symbolicznym


#!/bin/bash

if [ ! -e moj_plik ] ;then
echo "Plik nie istnieje"
elif [ -f moj_plik ] ;then
echo "Zwykły plik"
elif [ -d moj_plik ];then
echo "Katalog"
elif [ -L moj_plik ];then
echo "Dowiazanie symboliczne"
else
echo "Nie moge dopasowac rodzaju pliku"
fi

Skrypt pyta o hasło i sprawdza czy jest poprawne


#!/bin/bash

echo "Podaj haslo"

read haslo

if [ "$haslo" = "tajne" ]
then
echo "Prawidlowe haslo"
else
echo "Dostep zabroniony"
fi


Skrypt pyta o hasło i sprawdza czy jest poprawne
wersja z niewidocznym hasłem


#!/bin/bash
printf "Podaj haslo: "
stty -echo
read haslo
stty echo

if [ "$haslo" = "tajne" ]
then
echo "Prawidlowe haslo"
else
echo "Dostep zabroniony"
fi


Lista ważniejszych warunków:

-e plik - prawda, jeśli plik istnieje
-d plik - prawda, jeśli plik istnieje i jest katalogiem
-f plik - prawda, jeśli plik istnieje i jest zwykłym plikiem
-L plik - prawda, jeśli plik istnieje i jest dowiązaniem symbolicznym
-r plik - prawda, jeśli plik istnieje i można go czytać
-w plik - prawda, jeśli plik istnieje i można do niego pisać
-x plik - prawda, jeśli plik istnieje i można go wykonywać
-s plik - prawda, jeśli plik istnieje i ma rozmiar większy od zera
-g plik - prawda, jeśli plik istnieje i ma ustawiony bit set-group-id
-u plik - prawda, jeśli plik istnieje i ma ustawiony bit set-user-id
-b plik - prawda, jeśli plik istnieje i jest urządzeniem blokowym
-c plik - prawda, jeśli plik istnieje i jest urządzeniem znakowym


plik1 -nt plik2 - prawda, jeśli plik1 jest nowszy (zgodnie z datą modyfikacji) niż plik2
plik1 -ot plik2 - prawda, jeśli plik1 jest starszy niż plik2
plik1 -ef plik2 - prawda, jeśli plik1 i plik2 mają te same numery urządzenia i i-węzła


-z ciąg - prawda, jeśli ciąg długość równą zero
-n ciąg - prawda, jeśli ciąg długość większą od zera
ciąg1 = ciąg2 - prawda, jeżeli ciągi są jednakowe
ciąg1 != ciąg2 - prawda, jeżeli ciągi są różne
! wyrażenie - prawda, jeżeli wyrażenie jest fałszywe


wyrażenie -a wyrażenie -prawda, jeśli oba wyrażenia są prawdziwe
wyrażenie -o wyrażenie - prawda, jeżeli przynajmniej jedno z wyrażeń jest prawdziwe


argument1 -eq argument2 - prawda, jeśli argument1 jest równy argumentowi2
argument1 -ne argument2 - prawda, jeśli argument1 jest różny od argumentu2
argument1 -gt argument2 - prawda, jeśli argument1 jest większy od argumentu2
argument1 -ge argument2 - prawda, jeśli argument1 jest większy lub równy argumentu2
argument1 -lt argument2 - prawda, jeśli argument1 jest mniejszy od argumentu2
argument1 -le argument2 - prawda, jeśli argument1 jest mniejszy lub równy argumentowi2
Instrukcja wyboru Case
Składnia case wygląda następująco

case $nazwa_zmiennej in
"wzorzec1") polecenie1 ;;
"wzorzec2") polecenie2 ;;
.
.
.
*)polecenie
esac
Prosty przykład menu zbudowanego za pomocą case:

#!/bin/bash

echo "Wybierz opcje"
echo "1) Opcja-1"
echo "2) Opcja-2"
echo "3) Opcja-3"

read wybor

case $wybor in
1) echo "Wybrales 1";;
2) echo "Wybrales 2";;
3) echo "Wybrales 3";;
*) echo "Wybrales nieznana opcje" ;;
esac

Skrypt pyta o hasło i sprawdza czy jest poprawne
wersja z uzyciem petli while i instrukcji case


#!/bin/bash
while [ 1 ]
do
echo "Podaj haslo dostepu, q - wychodzi ze skryptu"
echo -n "Haslo: "
read haslo

case $haslo in
"admin") echo "Hasło poprawne, witaj adminie" ; break ;;
"student") echo "Hasło poprawne, witaj studencie" ; break ;;
"q") echo "Wyjscie" ; exit ;;
*)continue ;;
esac
done
Dzięki użyciu instrukcji case kod jest bardziej przejrzysty, poza tym teraz łatwo można przyporządkować każdej osobie opowiednie polecenia (oddzielamy je średnikami).
Skrypt pokazujący dialog z użytkownikiem:

#!/bin/bash

powitanie="Dzien dobry"
pan="Panu"
pani="Pani"

echo "Czy jestes mezczyzna? (T/N)"
read plec

case $plec in
t) echo "$powitanie $pan";;
T) echo "$powitanie $pan";;

n) echo "$powitanie $pani";;
N) echo "$powitanie $pani";;

*) echo "Niezrozumiala odpowiedz" ;;
esac
Taki sam skrypt napisany z użyciem warunków:
#!/bin/bash

powitanie="Dzien dobry"
pan="Panu"
pani="Pani"

echo "Czy jestes mezczyzna? (T/N)"
read plec

if [ "$plec" = "t" ] || [ "$plec" = "T" ]
then
echo "$powitanie $pan"

elif [ "$plec" = "n" ] || [ "$plec" = "N" ]
then
echo "$powitanie $pani"
else
echo "Niezrozumiala odpowiedz"
fi
Instrukcja wyboru select-case
Jest bardzo podobna do instrukcji Case. Dzięki niej łatwo zbudować menu (nie potrzeba stosować echo do wyświetlania opcji)

Składnia:

select nr in 1 2 3
do
case $nr in
"1") Polecenie1
"2") Polecenie2
"3") Polecenie3
"*") Polecenie
esac
break
done
Poniżej skrypt pokazujący jak można zbudować menu za pomocą instrukcji wyboru select-case
Skrypt WYBIERZ EDYTOR
wersja korzystająca z instrukcji select case

#!/bin/bash
select nr in vi mcedit pico wyjscie
do
case $nr in
"vi") vi ; break ;;
"mcedit") mcedit ; break ;;
"pico") pico ; break ;;
"wyjscie") echo "wyjscie" ; exit ;;
*) continue ;;
esac
break
done
Pętle
Pętla wykonuje jakieś działanie wiele razy. Może to być wyświetlanie, zliczanie bądź numeracja wielu plików, pytanie o hasło dopóki użytkownik nie poda właściwego czy dodawanie do siebie wielu kolejnych liczb.
While
Pętla while wykonuje działanie tylko wtedy gdy warunek jest spełniony.


Składnia:

while warunek_jest_prawdziwy
do
instrukcje
done

czyli:

dopóki warunek_jest_prawdziwy
wykonuj
instrukcje
zakończ

Poniżej przedstawiam prosty skrypt wyświetlający liczby do 1 do 10.

#!/bin/bash

a=1
while [ $a -le 10 ] # dopoki $a <= 10
do
echo "Biezaca liczba: $a" # wyswietlenie biezacej zmiennej
a=$[a+1] # zwiekszenie licznika o 1
done

Instrukcje break i continue służą do sterowania przebiegiem pętli.

- break - powoduje natychmiastowe wyjście poza pętlę
- continue - powoduje natychmiastowe wykonanie następnego przejścia pętli, bez wykonywania dalszych instrukcji

Instrukcja exit powoduje natychmiastowe wyjście ze skryptu.
Pętla nieskończona.

Jeśli napiszemy:

while [ 1 ]
do
instrukcje
done

to pętla ta będzie wykonywać się bez końca. Jednak dzięki wstawieniu instrukcji break możemy bez żadnego problemu wyjśc z pętli kiedy jest to potrzebne np:

while [ 1 ]
do
echo "Wpisz koniec aby zakonczyc"
read kod
if [ "$kod" = "koniec" ]
then
break
fi
done

echo "Jestem poza petla !"

Jeśli w przypadku wpisania "wyjscie" chcielibyśmy opuścić całkowicie skrypt - używamy instrukcji exit:

while [ 1 ]
do
echo "Wpisz koniec aby zakonczyc"
read kod
if [ "$kod" = "koniec" ]
then
exit
fi
done

echo "To sie nigdy nie wyswietli"
Jeśli chcemy aby po wpisaniu nieprawidłowego hasła komputer zapytał nas o to jeszcze raz (a nawet więcej) to najwygodniej użyć pętli:

Skrypt pyta o hasło i sprawdza czy jest poprawne
wersja z uzyciem petli while
Aby wyjsc nie podajac hasla trzeba nacisnac klawisze CTRL+C


#!/bin/bash

while [ 1 ]
do
echo -n "Podaj haslo: "
read haslo
if [ "$haslo" = "tajne" ]
then
echo "Prawidlowe haslo"
break # wyjscie z petli
else
echo "Dostep zabroniony"
continue # kolejne przejscie petli
fi
done

Jeśli mamy więcej pasujących haseł zamiast:

if [ "$haslo" = "tajne" ]

możemy napisać następująco:

if [ "$haslo" = "tajne" ] || [ "$haslo" = "inne" ]

Znak: || oznacza tzw. sumę logiczną czyli "lub"


Elegancko byłoby dodać opcję wyjścia gdy nie znamy hasła
Użyjemy do tego instrukcji case, służącej do porównywania ze wzorcem

Skrypt MENU
wersja korzystająca z instrukcji case
oraz działająca w pętli while

#!/bin/bash
while [ 1 ]
do
clear # Czysci ekran
echo "Wybierz edytor który chcesz uruchomić"
echo "1 - vi"
echo "2 - mcedit"
echo "3 - pico"
echo "4 - wyjscie"

read nr
case $nr in
"1") vi ; break ;;
"2") mcedit ; break ;;
"3") pico ; break ;;
"4") echo "Wyjscie" ; exit ;;
*) continue ;;
esac
done

Skrypt WYBIERZ EDYTOR
wersja korzystająca z instrukcji select case
oraz działająca w pętli while


#!/bin/bash
while [ 1 ]
do
select nr in vi mcedit pico wyjscie
do
case $nr in
"vi") vi ; break ;;
"mcedit") mcedit ; break ;;
"pico") pico ; break ;;
"wyjscie") echo "wyjscie" ; exit ;;
*) continue ;;
esac
break
done
done
Pętla Until
Pętla until jest odwrotością pętli while. Wykonuje się dopóki warunek jest fałszywy.
Składnia:

while warunek_jest_prawdziwy
do
instrukcje
done

czyli:

dopóki warunek_jest_prawdziwy
wykonuj
instrukcje
zakończ

Poniżej przedstawiam prosty skrypt wyświetlający liczby do 1 do 10.

#!/bin/bash

a=1
until [ $a -ge 10 ] # dopoki $a >= 10
do
echo "Biezaca liczba: $a" # wyswietlenie biezacej zmiennej
a=$[a+1] # zwiekszenie licznika o 1
done
Pętla for
Pętla for wykonuje to samo działanie dla wielu liczb, wyrazów, plików itp.
Istnieją dwie wersje pętli for. Pierwsza jest bardzo podobna do tej spotykanej w innych językach programowania:

Składnia:

for (( zmienna = 0 ; zmienna <= 5; zmienna++ )) # Wykonuj petle liczac od 0 do 5
do # wykonaj
... # jakieś instrukcje
done # koniec pętli

Przykład:

#!/bin/bash

for (( i = 0 ; i <= 5; i++ ))
do
echo "Witam $i raz"
done

wyświetli:

Witam 0 raz
Witam 1 raz
Witam 2 raz
Witam 3 raz
Witam 4 raz
Witam 5 raz

Druga wersja jest szczególnie ukierunkowana na działania na plikach.

Składnia:

for zmienna in lista # dla każdej wartości znajdującej się na liście
do # wykonaj
... # jakieś instrukcje
done # koniec pętli
Wyświetlenie liczb 1-5:
#!/bin/bash
for nr in 1 2 3 4 5
do
echo $nr # wyświetl bieżącą zmienną
done
echo "Petla zakonczona"
Jeśli chcielibyśmu odzielić liczby wynikowe spacjami (a nie znakami nowego wiersza), możemy to zrobić dopisując parametr -n do polecenia echo:
#!/bin/bash
for motor in 1 2 3 4 5
do
echo -n $nr
echo -n " "
done
echo # wyswietlenie znaku nowego wiersza
Zmienne na liście mogą być też łańcuchami:
Wyświetlenie marek motocykli
#!/bin/bash
for motor in Honda Yamaha Suzuki Kawasaki Harley
do
echo $motor # wyświetl bieżącą zmienną
done
Jeśli chcielibyśmy odzielić spacją wyniki, można to zrobić następująco
Wyświetlenie plików znajdujących się w bieżącym katalogu przy pomocy pętli for
#!/bin/bash
for plik in * # gwiazdka oznacza wszystkie pliki w bieżącym katalogu
# mozna zapisać dowolną inną ścieżkę
do
echo $plik
done
Wyświetlenie plików znajdujących się w /etc/* przy pomocy pętli for

#!/bin/bash
for plik in /etc/*
do
echo $plik
done
Skrypt zmienia prawa dostępu plikow z rozszerzeniem *.exe znajdujących się w bieżącym katalogu przy pomocy pętli for
#!/bin/bash
for plik in *.exe
do
echo -e "Zmieniam prawa dostępu do pliku\t $plik"
chmod 755 $plik
done
Za pomocą pętli for możemy dokonać dowolnej operacji na każdym z plików:
Skrypt łączący w jedną całość pliki *.txt w bieżącym katalogu
#!/bin/bash
for plik in `ls *.txt` # lub $(ls *.txt)
do
cat $plik >> calosc.txt
done
Wyświetlenie plików z podaniem kryteriów wyszukiwania przy pomocy pętli for
#!/bin/bash
echo "Podaj sciezkę dostępu do katalogu(np. /etc)"
read sciezka
echo "Kryteria wyswietlania(np. *, [ao]la itp.)"
read kryteria
for plik in $sciezka/$kryteria
do
echo $plik
liczba_plikow=$[ liczba_plikow+ 1] # zliczanie wyświetlonych plików
done

echo
echo "Liczba wyświetlonych plików: $liczba_plikow"
Skrypt łączący w jedną całość pliki *.txt w bieżącym katalogu
wersja rozszerzona
#!/bin/bash

# jesli istnieje plik calosc.txt zapytaj co robic
if [ -f calosc.txt ]; then
echo "Plik calosc.txt juz istnieje. Usunac jego zawartosc? (T/N)"
while [ 1 ]
do
read usun
if [ "$usun" = "T" ] || [ "$usun" = "t" ] ;then
rm calosc.txt
break
elif [ "$usun" = "N" ] || [ "$usun" = "n" ] ;then
break # przejdz dalej (czyli dopisze do pliku)
else
echo "Nieprawidlowy wybor. Wcisnij T lub N."
continue # wybierz ponownie
fi
done
fi

ilosc=0

for plik in `ls *.txt` # lub $(ls *.txt)
do
# jesli wlasnie przetawarzany plik to plik wynikowy
# bo tez ma rozszerzenie *.txt a wiec program bierze go pod uwage,
# opusc go (przejdz do nastepnego pliku w petli)
# inaczej dodalby zawartosc pliku wynikowego do jego samego

if [ "$plik" = "calosc.txt" ];then continue; fi

echo -e "\nNazwa pliku: $plik" >> calosc.txt # dodanie nazwy pliku
echo -e "----zawartosc-------\n" >> calosc.txt
cat $plik >> calosc.txt
let ilosc=ilosc+1 # licznik plikow
done

echo -e "\nDodano zawartosc $ilosc plikow\n"

echo -n "Wyswietlic wynikowy plik? (T) "
read pokaz
if [ "$pokaz" = "T" ] || [ "$pokaz" = "t" ]
then
echo -e "\nZawartosc pliku calosc.txt:\n"
cat calosc.txt
fi
Funkcje
Funkcje są bardzo przydatne ponieważ pozwalają nam na wielokrotne używanie kodu oraz dzielenie go na mniejsze części - odpowiadające tylko za jedną rzecz np. wysyłanie e-maila.

Przykład skryptu z funkcjami:


#!/bin/bash

# deklaracja funkcji
function powitanie
{
echo "Witaj !"
}

# wywołanie funkcji
powitanie

Po uruchomieniu skryptu zobaczymy napis "Witaj !".

Funkcję możemy wywołać dowolną ilość razy

#!/bin/bash

function powitanie
{
echo "Witaj !"
}

powitanie
powitanie

oraz z dowolnej instrukcji/pętli

#!/bin/bash

function wyswietl
{
ls -l
}

function zakonczenie
{ exit
}
echo "Co chcesz wykonać?"
select opcja in WYSWIETLIC_PLIKI ZAKONCZYC
do
case $opcja in WYSWIETLIC_PLIKI) wyswietl ;;
ZAKONCZYC) zakonczenie;;
esac
break
done

Programujący wcześniej w innych językach pewnie zastanawiają się czy można przekazać parametry do funkcji. Oczywiście że tak. Robi się to następująco:

#!/bin/bash

function param
{
echo -n "Oto pierwszy parametr: "
echo $1
echo -n "A to drugi: "
echo $2
}

param dlugosc 23


Funkcja może również zwracać wartość a więc przekazywać nam wynik obliczeń lub informować czy polecenia przez nią wykonywane zostały zakończone poprawnie. Używamy do tego instrukcji return. Zwrócona wartość znajduje się w zmiennej $?.

dodaj()
{
wynik=`expr $1 + $2`
return $wynik
}

dodaj 1 2

echo "Wynikiem dodawania jest $?"


Ostatnio zmieniony przez KOSA dnia Nie 14:22, 15 Cze 2008, w całości zmieniany 1 raz
Powrót do góry
Zobacz profil autora
Wyświetl posty z ostatnich:   
Napisz nowy temat   Odpowiedz do tematu    Forum www.ispwsznysa.fora.pl Strona Główna -> Systemy operacyjne I Wszystkie czasy w strefie CET (Europa)
Strona 1 z 1

 
Skocz do:  
Możesz pisać nowe tematy
Możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach

fora.pl - załóż własne forum dyskusyjne za darmo
Powered by phpBB © 2001, 2005 phpBB Group
Regulamin