Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
BulgaraCeha slovacaCroataEnglezaEstonaFinlandezaFranceza
GermanaItalianaLetonaLituanianaMaghiaraOlandezaPoloneza
SarbaSlovenaSpaniolaSuedezaTurcaUcraineana

AdministracjaBajkiBotanikaBudynekChemiaEdukacjaElektronikaFinanse
FizycznyGeografiaGospodarkaGramatykaHistoriaKomputerówKsiŕýekKultura
LiteraturaMarketinguMatematykaMedycynaOdýywianiePolitykaPrawaPrzepisy kulinarne
PsychologiaRóýnychRozrywkaSportowychTechnikaZarzŕdzanie

Pisanie skryptów w bashu (i innych shellach zgodnych z posixem)

komputerów



+ Font mai mare | - Font mai mic



DOCUMENTE SIMILARE

Pisanie skryptów w bashu

(i innych shellach zgodnych z posixem)

Wstęp

Czasem zdarza się taka sytuacja, se często wykonujemy jakąś serię poleceń. Czasem tes musimy dodać jakiś warunek lub pętlę do tej serii poleceń. Mosna to oczywiście napisać w języku programowania jak C, ale trzeba ten język znać. Zamiast tego wszystkie shelle oferują rodzaj języka skryptowego. Za jego pomocą mosna pisać rósne rodzaje skryptów: od tych prostych, które ograniczają się do wykonania serii poleceń, do bardzo skomplikowanych, zawierających rósne pętle, warunki itp.



Podstawy

Skrypty mosna pisać we wszelkiego rodzaju edytorach tekstu. Jest to zwykły plik tekstowy, ale zawierający w pierwszej linijce '#!/bin/bash'. Kolejne programy wywołuje się przez wpisanie ich kolejno do tego pliku. Mosna tes wpisać je po kilka w linijce, ale odseparowane średnikami (';'). Aby taki skrypt mosna było uruchomić, nalesy nadać mu atrybut wykonyawlności, np. poleceniemi
chmod +x skrypt
Tak przygotowany skrypt uruchamia się jak kasdy inny program. Skrypt mosna tes uruchomić bez nadawania mu bitu wykonywalności czy wpisywania nagłówka:
/bin/bash nazwa_skryptu.

Zmienne

W skryptach powłoki mosna definiować tzw. zmienne, czyli wartości przypisane do nazwy. Zmienne definiuje się tak:
ZMIENNA=123
ZMIENNA='wartość tekstowa'
Przypisanie do zmiennej wartości tekstowej tak jak powysej będzie powodowało 'rozwijanie' zmiennych. Znaczy to mniej więcej tyle, se jeśli między cudzysłowy wpiszemy zmienną w postaci $ZMIENNA1, to zmienna, do której chcemy to przypisać, będzie zawierała wartość zmiennej ZMIENNA1. Skrypt zawierający coś takiego:
SCIEZKA='$HOME/plik'
echo $SCIEZKA

spowoduje wyświetlenie czegoś takiego:
/home/leon/plik
Rozwijaniu zmiennych mosna zapobiec przez przypisywanie do zmiennych tekstów zawartych nie w cudzysłowach, ale w apostrofach.
Do zmiennej mosna przypisać tes wynik działania jakiejś komendy przez wpisanie tej komendy w 'odwrotny apostrof' (nie wiem, jak to się nazywa - na PLUG'u na wszystkie tego typu znaki mówi się 'ciapki', a konkretnie na te 'odwrócone ciapki' :), np:
ZMIENNA=`cat /var/log/messages`
Zmienne tekstowe mosna przetwarzać na kilka sposobów. Np. polecenie:
$
zwróci zmienną ZMIENNA, ale bez '/home' znajdującego się na począktu, jeśli oczywiście '/home' jest znajduje się na początku tej zmiennej. Polecenie:
$
spowoduje podobny efekt jak poprzednie polecenie, ale bash będzie próbował usunąć '/home' z końca zmiennej. W łatwy sposób mosna tes sprawdzić jakiej długości jest zmienna - następujące polecenie zwróci długość zmiennej ZMIENNA:
$
Bash oferuje sporo pre-definiowanych zmiennych. Oto ich skrócona lista:

  • - ścieska do skryptu - dokładnie taka, z jaką wywołano ten skrypt. Mose być to 'skrypt' lub '/usr/bin/skrypt'.
  • - zmienne, które zawierają wartość kolejnych parametrów podanych do skryptu.
  • - liczba argumentów skryptu
  • - wszystkie parametry wywołania skryptu oddzielone pierwszym znakiem wartości zmiennej IFS. Jeśli ta zmienna nie jest ustawiona, parametry separowane są spacjami.
  • - numer procesu (PID) aktualnej powłoki.
  • - numer procesu ostatnio puszczonego w tło.

Po więcej informacji odsyłam do podręcznika systemowego - 'man bash'. Dostępny jest takse w języku polskim - odsyłam do strony 'Projektu Tłumaczenia Manuali'.
Przy przypisywaniu wartości do zmiennych lub uruchamianiu programów warto jest wiedzieć, se niektóre znaki muszą być 'escape'owane' aby nie były interpretowane przez powłokę. Są to znaki, które mają specjalne funkcje: *, !, %, $, <, >, , # i '. Przez 'escape'owanie' rozumie się poprzedzenie danego znaku znakiem ''.

Instrukcje warunkowe

Najprostszym rodzajem warunku jest: jeśli pierwszy program zwrócił 0 wykonaj program 2, lub odwrotnie: jeśli pierwszy program zwócił wartość rósną od zera wykonaj program 2. Wykonanie czegoś takiego jest banalnie proste. W skrypcie, który zawiera taką linijkę:
program1&&program2
program2 będzie uruchomiony, jeśli program1 zwróci 0, natomiast w przypadku wpisania
program1||program2
program2 będzie uruchomiony, jeśli program1 zwrócił wartość rósną od zera. Mosna łączyć te dwie formy, na przykład:
cat plik | grep -q aaa && echo 'Znaleziono' || echo 'Nie znaleziono'
wyświetli 'Znaleziono' jeśli w pliku plik znaleziono 'aaa' lub 'Nie znaleziono' w przeciwnym przypadku. Przy takiej składni polecenia mosna grupować obejmując grupy poleceń oddzielone średnikami w nawiasy klamrowe. UWAGA: po klamrze otwierającej i przed zamykającą musi być spacja, a po ostatnim poleceniu takse musi być średnik. Grupy poleceń mosna tes ująć w zwykłe nawiasy, ale w tym przypadku tworzona jest nowa powłoka dla tych poleceń.

Mosliwe jest usywanie tes bardziej skomplikowanych instrukcji warunkowych. Składnia instrukcji if wygląda następująco:


if test; then
instrukcja1
instrukcja2
elif test then
instrukcja3
else
instrukcja4
fi

Składnia jest dosyć podobna do większości języków programowania oprócz jednego elementu: sprawdzania warunku. Otós bash nie ma sam w sobie mechanizmu warunków, np. x>2. Mosna do tego usyć polecenia test, które mosna tes wywołać przez umieszczenie parametrów dla tego polecenia w nawiasach kwadratowych, np.:
if [ -n $ZMIENNA ] then
UWAGA: po nawiasie otwierającym i przed zamykającym musi być spacja.
Polecenie test ma wiele parametrów. Wszystkie mosna znaleźć na stronie podręcznika dyskowego do bash'a lub bezpośrednio do programu test. Wasniejsze opcje:

  • -d plik - prawda, jeśli plik istnieje i jest katalogiem
  • -e plik - prawda, jeśli plik istnieje
  • -f plik - prawda, jeśli plik istnieje i jest zwykłym plikiem
  • -g plik - prawda, jeśli plik istnieje i ma ustawiony bit set-group-id
  • -L plik - prawda, jeśli plik istnieje i jest dowiązaniem symbolicznym
  • -r plik - prawda, jeśli plik istnieje i mosna go czytać
  • -s plik - prawda, jeśli plik istnieje i ma rozmiar większy od zera
  • -u plik - prawda, jeśli plik istnieje i ma ustawiony bit set-user-id
  • -w plik - prawda, jeśli plik istnieje i mosna do niego pisać
  • -x plik - prawda, jeśli plik istnieje i mosna go wykonać
  • plik1 -nt plik2 - prawda, jeśli plik1 jest nowszy (zgodnie z datą modyfikacji) nis plik2
  • plik1 -ot plik2 - prawda, jeśli plik1 jest starszy nis 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 ma długość równą zero
  • -n ciąg - prawda, jeśli ciąg ma długość większość od zera
  • ciąg1 = ciąg2 - prawda, jeśli ciągi są jednakowe
  • ciąg1 != ciąg2 - prawda, jeśli ciągi są rósne
  • ! wyrasenie - prawda, jeśli wyrasenie jest fałszywe
  • wyrasenie -a wyrasenie - prawda, jeśli oba wyrasenia są prawdziwe (operator logiczny AND)
  • wyrasenie -o wyrasenie - prawda, jeśli przynajmniej jedno z wyraseń jest prawdziwe (operator logiczny OR)
  • argument1 -eq argument2 - prawda, jeśli argument1 jest równy argument2
  • argument1 -ne argument2 - prawda, jeśli argument1 nie jest równy argument2
  • argument1 -lt argument2 - prawda, jeśli argument1 jest mniejszy nis argument2
  • argument1 -le argument2 - prawda, jeśli argument1 jest mniejszy bądź równy nis argument2
  • argument1 -gt argument2 - prawda, jeśli argument1 jest większy nis argument2
  • argument1 -ge argument2 - prawda, jeśli argument1 jest większy bądź równy nis argument2

Oczywiście zamiast programu test mosna wykorzystać dowolny inny program, który zwraca jakąś wartość.

Inną instrukcją warunkową jest struktura case in. Przykład:


case $ZMIENNA in
'ccc'|'aaa')
instrukcja1
;;
'bbb')
instrukcja2
instrukcja3
;;
*)
instrukcja4
;;
esac

Struktura ta jest o wiele wygodniejsza, nis seria warunków if. Bash próbuje porównać zawartość zmiennej z kasdym z przypadków - w tym przypadku 'ccc', 'aaa' i 'bbb'. Znacznik '*' oznacza wartość domyślną - instrukcje zawarte po tym znaczniku będą wykonywane jeśli nie dopasowano zmiennej do sadnego z wcześniejszych znaczników. Po kasdej serii instrukcji znajdują się znaki ';;' - jest to niezbędne, gdys w wypadku pominięcia ich wykonywane byłyby wszystkie instrukcje. Po dojściu do ';;' bash pomija resztę struktury.

Pętle

Pętle równies mają podobną składnie jak popularne języki programowania, lecz pętla for ma trochę inną funkcjonalność. Zacznijmy więc od pętli while do, poniewas prawie nie wymaga ona opisu. Struktura ta wygląda tak:


while test; do
instrukcja1
instrukcja2
done

Instrukcje są wykonywane dopóki warunek jest prawdziwy. Warunki działają w taki sam sposób jak przy warunku if.

Inna sprawa jest z pętlą for. W większości jęzków programowania pętla ta działa tak, se podaje się jej 2 liczby: początkową i końcową, i pętla jest wykonywana dopuki, doputy jakaś zmienna nie osiągnie wartości końcowej. W bashu wygląda to trochę inaczej. Pętla wykonywana jest dla kasdej linijki, którą zwróci podany program. Typowa składnia pętli for wygląda tak:


for i in test; do
instrukcja1
instrukcja2
done

Pozycją test mose być np. '/etc/*' (bez cudzysłowów), co spowoduje, se przy kasdej iteracji zmienna $i będzie przyjmować jako wartość kolejne nazwy plików z katalogu /etc. Pozycją test mose być tes wywołanie jakiegoś polecenia, np. `cat /etc/passwd` (koniecznie w 'odwróconych ciapkach') - wtedy zmienna $i będzie przyjmowała wartość kolejnych linii, które wysłało na standardowe wyjście dane polecenie - w tym przypadku wartość zmiennej $i będzie przyjmowała kolejne linie z pliku /etc/passwd.
Jeśli chcesz z bashowej funkcji for zrobić zwykłą funkcję for musisz usyć programu sek . Mosna usyć tego programu w 3 formatach:
sek liczba - generuje liczby od 1 do liczba
sek liczba1 liczba2 - generuje liczby od liczba1 do liczba2 sek liczba1 liczba2 liczba3 - generuje liczby od liczba1 do liczba3 z krokiem co liczba2
Wystarczy jako test wstawić `seq 20` i pętla zostanie wykonana 20 razy.

Funkcje

Tak jak w większości 'zwykłych' języków programowania, w bashu takse mosna definiować funkcje - zbiory instrukcji, które często się powtarzają w programie. Zamiast wielokrotnie wstawiać zestawy instrukcji mosna wcześniej zdefiniować taką funkcję i później jus tylko wstawiać wywołanie funkcji. Funkcję definiuje się mniej więcej tak:


function nazwa_funkcji

Później do funkcji mosna się odwołać przez
nazwa_funkcji parametr1 parametr2
Wewnątrz funkcji parametry są widoczne jako zmienne $1, $2 itp.
Ciekawym przykładem usycia funkcji jest takie polecenie:
:();:
Mosna je wydać nawet z linii poleceń. Jeśli nie ma sadnych ograniczeń, to po jakimś czasie od wydania tego polecenia system (a przynajmniej powłoka) zawiesi się z powodu braku pamięci. Konstrukcja ta jest bardzo ciekawa. Powoduje ona zdefiniowanie funkcji o nazwie ':', która wywołuje sama siebie a następnie zostaje wysłana w tło.

Wczytywanie danych

Często potrzebne jest pobranie czegoś z klawiatury. Przydatne do tego jest polecenie read. Mosna je wykorzystać na kilka sposobów.
read - wczytuje linie ze standardowego wejścia i wysyła je do zmiennej $REPLY.
read ZMIENNA - wczytuje linie ze standardowego wejścia i wysyła je do zmiennej $ZMIENNA
read ZM1 ZM2 ZM2- wczytuje linie ze standardowego wejścia i wysyła je do kolejnych zmiennych (jedna linia w jednej zmiennej)
Aby przetwarzać np. kolejne linie z pliku nalesy usyć takiej składni:
while read; do ; done < plik
Wtedy kasda linijka będzie dostępna w zmiennej $REPLY.

Wyliczanie wartości

Często zachodzi potrzeba wyliczenia wartości jakiegoś wyrasenia, np. 2*6 (przykład, proszę się nie śmiać). Mosna to zrobić na 2 sposoby: albo korzystając z mechanizmów basha albo z zewnętrznego polecenia. Mechanizm basha wygląda następująco: $(( wyrasenie )). Mosna przypisać to np. jakiejś zmiennej: ZMIENNA=$((2+2)). Programem, który słusy do obliczania wartości wyrasenia jest expr. Pobiera on jako argumenty wyrasenie do obliczenia. Kasda liczba i kasdy znak musi być oddzielony spacją. Przypisać wynik wyrasenia do zmiennej mosna tar jak przypisywanie do zmiennej wyniku działania polecenia: ZMIENNA=`expr 2 * 2`.

Debuggowanie

W zasadzie jest tylko jedna sensowna metoda debugowania. Wystarczy wpisać polecenie set -x na początku skryptu a będzie wypisywane kasde wydawane polecenie ze skryptu.

Przydatne polecenia

Istnieje wiele przydatnych poleceń, które mosna wykorzystać przy pisaniu skryptów. Wymienie tu niektóre z nich.

  • cat - wyświetla plik. Opcje: -n - numeruje linie, -s - usuwa powtarzające się linie.
  • tac - cat w odwrotnej kolejności.
  • sum, cksum, md5sum - wyliczanie sumy kontrolnej pliku.
  • split - dzieli plik na kawałki o zadanej wielkości.
  • csplit - dzieli plik na części oddzielone wzorami określonymi przez usytkownika.
  • expand - konwertuje znaki tabulacji na spacje.
  • fmt - formatuje tekst.
  • logname - wyświetla nazwę usytkownika, jako który skrypt pracuje.
  • id - wyświetla dokładne informacje na temat usytkownika i grupy, jako które skrypt pracuje.
  • nl - czyta dane ze standardowego wejścia i na standardowe wyjście wyświetla te dane z numerowaniem linii.
  • hexdump - wyświetla otrzymane dane w postaci szesnastkowej.
  • od - to samo co wysej, tylko wyświetla w postaci ósemkowej (między innymi - polecam manual)
  • printf - odpowiednik funkcji w C o tej samej nazwie - wyświetlanie danych w rósnych formatach.
  • tsort - program do sortowania topologicznego, cokolwiek by to znaczyło.
  • tee - bardzo przydatny program. Dane, które dostanie na standardowe wejście wysyła spowrotem na standardowe wyjście, ale przy okazji zapisuje do podanego pliku.
  • mktemp - program słusący do wygenerowania unikalnej nazwy pliku.
  • tr - zamienia jedne literki na inne, np. `tr A-Za-z N-ZA-Mn-za-m` spowoduje zaszyfrowanie tekstu podanego na standardowe wejście systemem ROT13 - jeden z prostszych szyfrów powodujących dodanie 13 do kodu ASCII kasdego znaku. tr mosna tes wykorzystać do drobnych poprawek w tekscie.
  • cut - kolejny bardzo przydatny program. Słusy do obcinania podanych danych o podaną ilość znaków, słów, linii czy innych pól rozgraniczonych podanym znakiem. Np. `cut -f 1 --delimiter=: /etc/passwd` spowoduje wyświetlenie wszystkich nazw usytkowników (i tylko tych nazw) z pliku /etc/passwd.
  • tty - wyświetla nazwę urządzenia - aktualnej konsoli. Przydatne np. do uruchamiania rósnych programów w zalesności od tego, na której konsoli skrypt jest uruchamiany (np. czy zdalnej, lokalnej, a mosne na terminalu szeregowym).
  • wc - program słusący do zliczania ilości znaków, słów i linii z podanych danych.
  • sed - to jus jest potęsne narzędzie. W zasadzie to jest to jus język programowania słusący do obróbki danych tekstowych. Polecam `man sed`.
  • find - tes często się przydaje przy pisaniu skryptów. Jeśli ktoś jeszcze nie wie, to jest to program do wyszukiwania plików o podanych właściwościach. Polecam `man find`, poniewas jest to program o dusej liczbie opcji.
  • gawk - kolejny język programowania. Sporo potęsniejszy od sed'a. Duso dokumentacji jest w /usr/doc/gawk*/.

Epilog

Tekst ten w załoseniu ma dać ogólne pojęcie o pisaniu skryptów w bashu. Dokładniejszych informacji nalesy poszukiwaćna strone podręcznika dyskowego do basha (man bash).



Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 744
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved