Skrypty powłoki
Skrypty w Linuksie
Po co pisać skrypty?
Podczas pracy w konsoli często wykonujemy wielokrotnie po kolei te same komendy, czasem nieco zmienione na przykład poprzez podanie innych plików wejściowych czy parametrów uruchamianych programów. Między innymi w takich wypadkach lepiej jest umieścić je w skrypcie, czyli pliku tekstowym, który uruchamia po kolei wpisane w nim komendy. Umieszczanie poleceń w skryptach ma jeszcze tę zaletę, że stanowi on dobrą dokumentację wykonywanych operacji. Pisanie skryptów jest w zasadzie programowaniem. Będziemy tu używać powłoki Bash
. Poza możliwościami uruchamiania różnych poleceń/programów, z czym mieliśmy dotychczas do czynienia, udostępnia ona także wiele elementów charakterystycznych dla języków programowania jak zmienne, kolekcje elementów czy pętle. Tutaj pokażę tylko kilka podstawowych elementów programowania w bash
-u.
Pierwszy skrypt
Utwórz plik tekstowy o nazwie pierwszy_skrypt.sh
. Umieść w nim kilka linii:
Przed uruchomieniem pliku musimy jeszcze dokonać pewnej modyfikacji. Samo przedłużenie .sh
(które zresztą jest opcjonalne) nie sprawia, że plik jest uruchamialny, najpierw trzeba mu nadać odpowiednie prawa:
Teraz można skrypt uruchomić:
Zauważ, że plik uruchamiamy podając przed nazwą ./
, jeśli skrypt znajduje się w bieżącym katalogu. Jeśli nie, to podajemy do niego pełną ścieżkę (są jeszcze inne rozwiązania jak np. umieszczanie skryptu w katalogach, w których domyślnie powłoka szuka programów/skryptów).
Uruchomiony skrypt, jak widać, wykonał po kolei umieszczone w nim polecenia. Tajemniczo może wyglądać pierwsza linia. Znak #
wskazuje na linię komentarza - czyli wszystko poza nim nie jest interpretowane przez powłokę. W tym przypadku, pierwszej linii skryptu, w połączeniu ze znakiem !
, wskazuje jakiej powłoki (języka) użyć do uruchomienia poleceń w skrypcie.
Skoro jednak już wspomniałem o komentarzach w skryptach to parę słów na ten temat. W komentarzach zwykle umieszczamy informacje na temat tego jaka jest ogólna funkcja skryptu, jak go używać, jak skrypt działa, czemu służą poszczególne polecenia itp. Przy pisaniu skryptów warto poświęcić trochę czasu aby go prawidłowo opisać w komentarzach. Po pierwsze sprzyja to dokumentacji pracy, po drugie jeśli po pewnym czasie wrócimy do skryptu, nie będziemy tracić czasu na przypominanie sobie ,,co autor miał na myśli''.
Zmienne
Zmienne pozwalają przechować a następnie wykorzystać pewne wartości, np. liczby, łańcuchy znaków.
Na początek utwórz plik zmienne.sh
z taką zawartością:
Zauważ, że przy tworzeniu zmiennych nie używamy znaku $
przy ich nazwie (plik
, tekst
), natomiast kiedy się do nich odwołujemy, umieszczamy znak $
na początku ($plik
, $tekst
). Przy znaku =
nie można wstawiać spacji. Znak $
czasem znajduje się w innym miejscu, co można zobaczyć np. na kolejnym przykładzie w którym pokażę jak używać zmiennych przechowujących liczby do prostych obliczeń:
Parametry (argumenty) przekazywane do skryptu i zmienne specjalne
Przy uruchamianiu skryptu, można przekazać parametry, takie jak np. nazwy plików z danymi, nazwy sekwencji, nazwy analizowanych gatunków itd. Podajemy je po nazwie skryptu, oddzielone spacjami. Jeśli przekazany parametr (np. tekst) zawiera spacje to całość obejmujemy cudzysłowami. Kolejne parametry przyjmują w skrypcie nazwy od $1 do $9. Nie oznacza to, że nie można ich przekazać więcej, ale można się do nich odwołać w inny sposób, np. używając pętli. Wszystkie parametry są przechowywane w $@
.
W skrypcie można się posługiwać domyślnymi nazwami ($1
..$2
) ale dla przejrzystości kodu lepiej ich wartość przypisać do zmiennych o nazwach, które odpowiadają ich funkcji. Na przykład jeśli parametr jest nazwą pliku, to zienna może nazywać się plik
albo plik_wejsciowy
.
Utwórz skrypt argumenty.sh
, nadaj mu uprawnienia wykonywalności.
Teraz go uruchom z dwoma parametrami:
Sprawdź zawartość pliku argumenty.txt
.
Istnieje wiele innych zmiennych specjalnych i środowiskowych, które się mogą przydać, np:
$0
- nazwa własna skryptu$HOME
- ścieżka do katalogu domowego bieżącego użytkownika$USER
- nazwa bieżącego użytkownika
Zmienne tablicowe
Być może zwróciłeś uwagę, że powyższa zmienna $@
przechowuje wiele wartości na raz. Jest to przykład zmiennej tablicowej.
Zmienne tablicowe przydają się gdy chcemy przechować wiele elementów (które mogą odpowiadać wielu zmiennym). Za chwilę wrócimy do nich przy okazji pętli. Na razie prosty przykład jak utworzyć taką zmienną i wypełnić ją danymi (zmienne_tablicowe.sh
):
W nawiasach kwadratowych znajduje się indeks (numer) wartości. Zauważ, że liczby zaczynają się od 0
a nie 1
. Wartość o indeksie 1
jest więc drugą a nie pierwszą. Znak @
lub *
oznacza wszystkie wartości.
Wynik:
Zmienne i wynik polecenia
Zmienna może przechowywać wynik działania polecenia. W takim wypadku polecenie należy albo umieścić w parze odwrotnych apostrofów ``
albo w parze nawiasów ze znakiem dolara $()
.
Sprawdź na przykładzie jak to działa (polecenia.sh
)
Przy okazji sprawdź jak zmienia się sposób wyświetlania zawartości zmiennych jeśli ich nazwy nie znajdą się w cudzysłowach.
Pętle i czytanie wartości z pliku tekstowego
Pętle pozwalają na wielokrotne wykonywanie tych samych czynności, często ze zmienionymi parametrami. Nie będę tu gruntownie omawiał pętli, pokażę tylko kilka przykładów pętli, które można zastosować w dalszych etapach kursu.
Pętla operująca na argumentach
Pierwszy przykład pokazuje jak coś zrobić z kolejnymi argumentami przekazywanymi do skryptu. Mogą to być np. nazwy plików z którymi będziemy coś robić (np. generować dla nich drzewa filogenetyczne). Na razie tylko wydrukujemy ich nazwy.
Skrypt petla_argumenty.sh
Teraz wywołaj skrypt z odpowiednimi parametrami:
Zamiast argumentów można użyć innej zmiennej tablicowej:
A teraz coś bardziej złożonego. Odczytywanie danych z pliku i wykorzystanie ich w pętli.
Najpierw utwórz plik tekstowy o nazwie dane.tsv
. Przedłużenie tsv
oznacza tab-separated values, więc dane oddziel tabulatorem a nie spacją.
W każdej linii znajduje się kolejno: nazwa sekwencji, numer GenBank z którego pochodzi fragment sekwencji i w końcu fragment sekwencji. Zwróć uwagę, żeby na dole pliku nie było pustej linii.
Teraz skrypt, który odczyta dane, a następnie na ich podstawie utworzy pliki z danymi (czytaj_z_pliku.sh
)
Kolejna pętla odczytuje wszystkie pliki fasta
z katalogu (odczyt_plikow.sh
)
Podsumowanie
Powyższe elementy pisania skryptów w Bash
-u to jedynie czubek góry lodowej. Zachęcam do dalszego samodzielnego zgłębiania tej cennej umiejętności. W dalszej części kursu pokażę bardziej praktyczne przykłady jej wykorzystania.
Last updated