Pobierz Firefoksa teraz i podpal sieć!

    

JĘZYK SKRYPTOWY SHELLA




Polecenia/programy shellowe można łączyć w ciągi poleceń - skrypty shellowe. Polecenia będą wykonywane w takiej kolejności w jakiej byłyby wpisywane z klawiatury. Jest to przydatne jeżeli w określony sposób przetwarzanych jest wiele plików lub duża ilość tekstu.  #oznacza komentarz
Wszystkie użyte polecenia zostały opisane w pliku shell. Aby wykonać skrypt należy najpierw za pomocą edytora wprowadzić polecenia do pliku. Następnie trzeba zmienić prawa dostępu do pliku tak aby plik był wykonywalny, np. chmod 755 plik. Plik można uruchomić poleceniem ./plik

PRZYKŁAD 1.
Wypisać liczby od 1 do 100

Ustawimy zmienną, która będzie przyjmowała w pętli wartości od 1 do 100 wypisując po każdej zmianie swoją wartość.

1:    a=1
2:    while [ $a -le 100 ]
3:    do
4:    echo $a
5:    a=`expr $a + 1`
6:    done
7:    #To jest komentarz. Skrypt wypisuje wartości od 1 do 100


Nie należy wstawiać do skryptu numerów na początku linii - służą one do opisu skryptu w tym dokumencie.
W linii 1 ustawiono zmienną a na 1. Można sprawdzić wartość ustawionej zmiennej przez odwołanie się do niej ze znakiem $:
a=1
echo $a


Linia 2 sprawdza warunek - while (dopóki) wartość zmiennej a jest -le (less or equal - mniejsze lub równe) wykonuj ciało pętli. Ciało pętli - instrukcje pomiędzy 3 do (wykonuj) i 6 done (zrobione) będą wykonywane tak długo jak długo wartość zmiennej a będzie mniejsza od 100. Należy zwrócić uwagę że [ ] oddzielone są spacją od swoich argumentów. Tabela przedstawia operatory porównań dla zmiennych liczbowych i tekstowych

Dla porównań liczbowych
-le
-ge
-eq
-lt
-gt
(less or equal)
(greater or equal)
(equal)
(less than)
(greater than)
<=
>=
=
<
 >
Dla porównań tekstowych
=
teksty są identyczne
!=
teksty są różne

np.
t=tekst
if [ "$t" = tekst ]
then
...
fi


Linia 4 wyświetla na konsoli bieżącą wartość zmiennej a. Linia 5 wykonuje dość skomplikowaną operację. Warto najpierw sprawdzić sam wynik polecenia
expr 6 + 3

expr (expression - wyrażenie) oblicza wartość arytmetyczną wyrażenia 6 + 3 i zwraca wynik równy 9. W linii 5 pojawiły się znaki ` ` . Oznaczają one uruchomienie nowego (pod)shella, wykonanie w nim polecenia zawartego w ` `, powrót do bieżącego shella i przekazanie wyniku, porównajmy:
a:    echo ls
b:   
echo `ls`
a) wyświetli na wyjściu tekst "ls" (ls jest traktowane jako tekst, nie jako polecenie). b) najpierw wykona w podshellu polecenie ls (wyświetli zawartość bieżącego katalogu), a wynik tego polecenia trafi jako argument dla echo (jako tekst, który ma zostać wyświetlony). W efekcie na wyjściu pojawi się listing katalogu, czyli tak samo jak po wydaniu polecenia:
c:    ls

Wracając do naszego przykładu - w linii 5 przy każdym wykonaniu pętli wartość a będzie się zwiększała o 1. Wynikiem działania skryptu będzie więc wyświetlenie zmieniającej się od 1 do 100 wartości a.
Po przedstawieniu ` ` warto od razu zaprezentować  " "  oraz  ' '.
a=/bin
1:    echo `ls $a`
2:    echo 'ls $a'
3:    echo "ls $a"


ls jest poleceniem shella jednak tylko w linii 1 ls będzie traktowane jako polecenie. W liniach 2 i 3 ls będzie traktowane jako zwykły tekst.
wynikiem 1 będzie wykonanie polecenia: echo (wyświetl) wynik polecenia ls $a, gdzie za $a zostanie podstawiona wartość a, czyli katalog /bin. Najpierw zostanie uruchomiony podshell, wykonane w nim polecenie ls /bin, a wynik zostanie przekazany (jako zwykły tekst) do echo. Podobny efekt uzyska się wpisując: ls /bin
wynikiem 2 będzie wyświetlenie: ls $a. Wszystko co zostało zawarte między ' ' zostanie zinterpretowane jako ciąg tekstowy (string). Żadne znaki specjalne shella (czyli $) nie będą interpretowane - będą traktowane jako zwykły tekst.
wynikiem 3 będzie wyświetlenie tekstu: ls /bin. " " pozwala na interpretację trzech znaków:
a:    $
b:    \
c:    ' '


a:    $ - wartość zmiennej. $ jest znakiem specjalnym shella. W tym miejscu shell podstawia wartość przechowywaną w zmiennej.
b:    \ - zasłonięcie specjalnego znaczenia znaku. Jeżeli $ jest znakiem specjalnym to jak wyświetlić na wyjściu znak $ ? Można zasłonić specjalne znaczenie $ przez \$. Wówczas $ będzie traktowany jako zwykły znak.
echo "ls \$a" wyświetli na wyjściu: ls $a
c:    ' ' - wewnątrz " " można umieścić ' '.
echo "$a '$a nie jest interpretowana'" wyświetli: /bin $a nie jest interpretowana


PRZYKŁAD 2.
Utworzyć 20 plików o nazwach plik<nr_pliku>, każdy zawierający tekst: to jest plik <nr_pliku>

W tym celu wystarczy zmodyfikować pierwszy skrypt. Wyjście polecenia echo jest standardowo kierowane na standardowe wyjście, czyli na ekran (konsolę). Używając operatora przekierowania możemy wyjście skierować do pliku.

1:    a=1
2:    while [ $a -le 20 ]
3:    do
4:    echo "to jest plik $a" > "plik$a"
5:    a=`expr $a + 1`
6:    done


W linii 4 użyto operatora przekierowania >. Shell pozwala na używanie następujących przekierowań:
strumien > plik         --wyjście będzie przekierowane do pliku. Plik będzie najpierw wyzerowany lub utworzony (jeżeli nie istniał)
strumien >> plik        --wyjscie zostanie dopisane do pliku (zostawiając poprzednią zawartość)
strumien < plik         --standardowym wejściem zamiast klawiatury będzie plik
polecenie_1 | polecenie_2 --potok - wyjście polecenia_1 będzie wejściem polecenia_2, np. cat /etc/passwd | grep root

Wykorzystanie potoków.
cat /etc/passwd | head -5 | tail -3 | cut -b 1-6

Mamy tutaj aż 4 polecenia. Najpierw cat wyświetla zawartość pliku /etc/passwd. Wyjście, czyli zawartość tego pliku kierowane jest na wejście do head. head zostawia tylko 5 pierwszych linii pliku. Tych 5 linii jest wejściem dla tail. tail -3 zostawia 3 ostatnie linie z tego co dostał na wejście od head. W tym momencie pozostała już tylko 3,4 i 5 linia pliku /etc/passwd. Te trzy linie stają się wejściem dla ostatniego polecenia cut. cut zostawia tylko znaki od 1 do 6 z tego co otrzmał na wejście, czyli z linii 3,4 i 5 pliku /etc/passwd.
Polecenie to może być prostsze do prześledzenia jeżeli będzie wykonywane etapami. Najpierw wystarczy wykonać samo:
cat /etc/passwd
potem
cat /etc/passwd | head -5, itd...


PRZYKŁAD 3.
Wszystkie pliki w bieżącym katalogu skopiuj na pliki z dodatkiem rozszerzenia .bak (np. plik1 na plik1.bak) do katalogu KOPIA.

1:    mkdir KOPIA
2:    for i in *
3:    do
4:    cp $i KOPIA/$i.bak
5:    done


pętla for może być używana do operacji na plikach. Do zmiennej i przypisywane są kolejno wszystkie pliki i katalogi użyte w linii 2 for. Można również użyć
for i in /dev/*  dla wszystkich plików w katalogu /dev
for i in pli*    dla wszystkich plików w bieżącym katalogu rozpoczynających się od pli


PRZYKŁAD 4.
Wczytaj wartość do zmiennej. Sprawdź czy jest ona nie większa od 10 i wypisz stosowny komunikat

1:    read a
2:    if [ $a -le 10 ]
3:    then
4:    echo "zmienna jest nie większa od 10"
5:    else
6:    echo "zmienna jest większa od 10"
7:    fi


Jeżeli warunek po if jest spełniony then (wtedy) zostaje wykonane ciało pętli. else (jeżeli warunek nie jest spełniony) wykonane zostaje ciało po else. fi kończy pętlę.

Mimo, że nie jest to kompletna wiedza na temat tworzenia skryptów zawarte w tym dokumencie informacje wystarczą do tworzenie skryptów realizujących nawet skomplikowane zadania.


Poniżej zamieszczam (głównie na własny użytek) różne przydatne polecenia:

1. Archiwizowanie danych przez sieć:
tar czf - /some/file | ssh user@host tar -xzf - -C /destination
tar czf - /some/file | ssh user@host cat ">" remotefile.tgz

2. Sprawdzanie zmian w cvs od danej daty do teraz
cvs diff -w -B -D 2003/08/29 -D now -N > log; less log
cvs diff -w -B -D 2003/08/29 -D now -N | grep "Index:" > log; less log


opracował Karol Kreński