Skrypty¶
Popularne interpretery¶
sh
— (Bourne shell) szeroko dostępny interpreterbash
— (Bourne-again shell) rozszerzona wersjash
fish
— (Friendly Interactive shell) interpreter z ułatwieniami dla użytkowników i programistówcsh
andtcsh
— (C shell) interpreter luźno oparty na składni języka Czsh
— (Z shell) rozszerzona wersjabash
-a
Wykonywanie skryptów¶
Lista komend zapisana w dowolnym pliku tekstowym może być wykonana za pomocą intepretera:
sh PLIK
bash PLIK
Pliki wewnętrznie oznacza się jako skrypt podając w pierwszej lini pliku
dyrektywę interpretera która informuje system operacyjny za pomocą jakiego
polecenia je otworzyć. Dyrektywa to pełna ścieżka programu do wykonania
poprzedzona znakiem komentarza i wykrzyknikiem #!
(tzw. shebang):
#!/bin/sh
#!/bin/bash
Można w ten sposób oznaczyć dowolny plik tekstowy do otwarcia za pomocą dowolnego programu:
#!/usr/bin/env python
#!/usr/bin/firefox
Plik tekstowy oznaczony dyrektywą można uruchomić:
- ./SKRYPT.sh – w katalogu bieżącym
- /home/user/SKRYPT.sh – pełna ścieżka (z dowolnego katalogu)
Żeby uruchomić plik należy mu nadać odpowiednie prawa (chmod
).
Parametry i zmienne¶
Skrypt może zostać uruchomiony z argumentami, np.:
./SKRYPT.sh a b c d
Argumenty są dostępne przez parametry pozycyjne (positional parameters):
$1 $2 $3 $4 ... ${10} ${11} ...
Polecenie shift n
przesuwa zawartość zmiennych o n
w lewo (domyślnie
n
= 1).
- Przykłady::
- shift # 1=$2, 2=$3, 3=$4 ... shift 2 # 1=$3, 2=$4, 3=$5 ...
Zmienne specjalne¶
$0
– ścieżka do skryptu (nazwa wykonywanego skryptu)$#
– liczba argumentów$*
– wszystkie parametry pozycyjne jako jeden napis ("$1 $2 ..."
$@
– wszystkie parametry pozycyjne jako osobne napisy ("$1" "$2" ...
)$$
– PID procesu skryptu
Tablice¶
Definicja:
array[0]=asia
array[1]=basia
array[2]=casia
array[a]=asia
array[b]=basia
array[c]=casia
Definicja całej tablicy:
array2=( asia basia casia )
array3=([0]=asia [0]=basia [0]=casia) # only int->whatever
Odczyt konkretnego elementu:
echo ${array[b]}
Wszystkie elementy tablicy:
echo ${array[@]}
echo ${array[*]}
Długość tablicy:
echo ${#array[@]}
echo ${#array[*]}
Kontrola zmiennych¶
Polecenia declare
i typeset
:
declare -r x=5 # deklaracja zmiennej tylko do odczytu echo $r r=6 declare -i y # deklaracja zmiennej o typie l. całkowita y=5 echo $z y="ala ma kota" echo $z declare -a arr # deklaracja tablicy
Komentarze¶
Komenatrze zaczynają się od znaku #
i kończą się wraz z końcem bieżącej
lini.
# Prawo Ohma
I=`expr $V / $R`
#echo "I=$V/$R -> $I"
# TODO Dodać prawo Kirchhoffa
Jakie zastosowania mają komentarze?
Konstrukcje językowe¶
Separatory instrukcji¶
Sposoby wykonania dwóch komend:
# wykonanie sekwencyjne
COMMAND1
COMMAND2
# wykonanie sekwencyjne
COMMAND1; COMMAND2
# wykonanie warunkowe
COMMAND1 && COMMAND2
# wykonanie warunkowe
COMMAND1 || COMMAND2
# wykonanie współbieżne
COMMAND1 & COMMAND2
# potok
COMMAND1 | COMMAND2
Konstrukcja if¶
if COMMAND0
then
INSTRUCTIONS
elif COMMAND1 # Opcjonalne
INSTRUCTIONS
else # Opcjonalne
INSTRUCTIONS
fi
Wykonywane instrukcje w zależności od stanu wykonania wskazanej komendy
COMMAND0
.
Przydatne polecenia:
false
– nie robi niczego i kończy się stanem 1true
– nie robi niczego i kończy się stanem 0test
– sprawdza wskazany warunek[ ]
– j/w tylko krócej(( ))
– sprawdza warunek arytmetyczny.$(( ))
– wykonuje działanie arytmetyczne
Konstrukcja case¶
case VALUE in
PATTERN0) INSTRUCTIONS;; # lub ;&
PATTERN1) INSTRUCTIONS;; # lub ;&
PATTERN2) INSTRUCTIONS;; # lub ;&
PATTERN3) INSTRUCTIONS;; # lub ;&
esac
Możliwa dowolna liczba warunków i dowolny blok instrukcji po każdym z warunków.
Przy zastosowaniu ;;
po przypasowaniu do warunku i wykonaniu
instrukcji wychodzi z konstrukcji case
. Przy zastosowaniu ;&
wykonuje instrukcje także kolejnego warunku.
- Przykłady warunków:
napis
– traktowany dosłownie*
– dowolny ciąg znaków[A-Z]
– klasa znaków?
– dowolny znakimage_199[0-9]\*.jp?g
– złożony warunek
Pętla while¶
while COMMAND
do
INSTRUCTIONS
done
Wykonywane instrukcje do czasu az stan wykonania komendy COMMAND
będzie
inny od 0
.
Przydatne instrukcje (dla każdego rodzaju pętli):
break
– przerywa działanie pętlicontinue
– przerywa wykonywanie instrukcji w ciele pętli i przechodzi do następnej iteracji
Pętla for¶
for VARIABLE_NAME in ARGUMENT_LIST
do
INSTRUCTIONS
done
Wykonuje instrukcje dla każdego z argumentów z ARGUMENT_LIST
.
Każdy z argumentów jest przypisywany kolejno do zmiennej VARIABLE_NAME
.
Alternatywna uproszczona składnia:
for VARIABLE_NAME
do
INSTRUCTIONS
done
Wykounje instrukcje dla każdego z argumentów (parametrów pozycyjnych) skryptu.
Pętla for à la C¶
for (( INIT_EXPR ; TEST_EXPR ; STEP_EXPR ))
do
INSTRUCTIONS
done
Gdzie: INIT_EXPR
jest wykonane przed pętlą, TEST_EXPR
jest wykonywane
przed każdą iteracją i wynik zwracany przez wyrażenie ($?
) powoduje
rozpoczęcie iteracji lub zakońćzenie pętli, STEP_EXPR
to wyrażenie
wykonywane po każdej iteracji.
(( INIT_EXPR ))
while (( TEST_EXPR ))
do
INSTRUCTIONS
(( STEP_EXPR ))
done
Pętla select¶
select VAR in ARGUMENT_LIST
do
INSTRUCTIONS
done
Zakończenie działania skryptu¶
exit
- Zakończ wykonywanie skryptu. Jako argument przyjmuje stan zakończenia. Domyślnie status 0.
Operacje wejścia/wyjścia¶
read
Wczytaj do zmiennej. (BASH shell bultin)
-p prompt znak (napis) zachęty -t timeout czas wygaśnięcia w sekundach -s nie wyświetlaj znaków wpisanych przez użytkownika
# Najprostszy przypadek
read i
echo $i
# Hasło wpisywane bez echa, max. przez 30 sekund
read -p "Password: " -s -t 30 password
echo $password
Funkcje¶
function NAME () { # Opcjonalne "function" lub "()"
INSTRUCTIONS
} REDIRECTION # Opcjonalne "REDIRECTION"
Przykłady:
# Przekierowuje echo na STDERR
function echo_err {
echo $@
} >&2
echo_err "Ala ma kota"
# Przeciąża polecenie echod
function echo {
if $DEBUG
then
echo $@
fi
}
# Sprawdza warunek i ustawia stan wyjścia
function fsm_spaghetti_day {
if [ `date +%A` == 'Friday' ]
then
exit 0
fi
exit 1
}
Zadania¶
- Skrypt tworzący nazwę projektu, zmiennej, itp. wg określonego formatu.
Jako pierwszy parametr podajemy nazwe formatu docelowego,
- Przykłady użycia:
./chcase joined my new project # Zwraca: mynewproject
./chcase underline my new var # Zwraca: my_new_project
./chcase uppercase my new const # Zwraca: MY_NEW_CONST
./chcase dashes my new resource # Zwraca: my-new-resources
Jeśli format nie zostanie podany wyświetl dostępne formaty i zakończ z błędem. Jeśli użytkownik nie poda argumentów, wyświetl krótką instrukcję i zakończ z błędem.
- Skrypt tworzacy kopie zapasowe wskazanych plików i katalogów. Jako pierwszy
parametr należy podać miejsce utworzenia kopii. Jako kolejne podajemy nazwy kopiowanych plików i katalogów. Do nazw kopiowanych zasobów dodana powinna być też data i czas utworzenia kopii.
- Przyklad użycia:
./bup /tmp/backup asia/ basia/ casia.txt
- Spowoduje powstanie plików:
/tmp/backup/10-05-12_10:03_asia/
/tmp/backup/10-05-12_10:03_asia/cokolwiek_było_w_katalogu
/tmp/backup/10-05-12_10:03_basia/
/tmp/backup/10-05-12_10:03_basia/cokolwiek_było_w_katalogu
/tmp/backup/10-05-12_10:03_casia.txt
Jeśli wskazany katalog docelowy nie istnieje to należy go utworzyć. Jeśli wskazany katalog docelowy istnieje ale nie jest katlogiem, należy zakończyć działanie z błędem.
Jeśli plik do kopiowania nie istnieje, należy go pominąć i na samym końcu działania programu wypisać ostrzeżenie, że plik nie został odnaleziony.
Skrypt który rozmawia z użytkownikiem. Użytkownik zadaje pytanie, skrypt losuje odpowiedź z pliku. Kiedy użytkownik napiszę kluczową frazę (np.
that's enough
) skrypt kończy rozmowę.Skrypt który czeka, aż zawartość określonej strony się zmieni. Jeśli zawartość się zmieniała, to skrypt wykonuje wskazaną komendę. Użytkownik może (ale nie musi) określić jak często skrypt ma sprawdzać kopie lokalną.
Przykład użycia:
# Przykładowa strona (zapisana do zmiennej dla wygody) WEBSITE=http://www.cs.put.poznan.pl/ksiek/SOP/resources/embrace_change.php # Sprawdza czy strona się zmieniła z domyślną częstotliwością. # Jeśli strona się zmieni to otwiera ją w przeglądarce internetowej. ./diditchange "$WEBSITE" firefox "$WEBSITE" # Sprawdza czy strona się zmieniła raz na 5 sekund. # Jeśli strona się zmieni to otwiera ją w przeglądarce internetowej. ./diditchange "$WEBSITE" -t 5 firefox "$WEBSITE"
Jeśli nie można połączyć się ze stroną skrypt powinien wyświetlić błąd i zakończyć działanie.
Przydatne polecenia:
wget
,sleep
.Skrypt-predykat który sprawdza porę dnia. Możliwe pory dnia: early, late, day, night, morning, lunchtime, evening
Przykłady użycia:
if ./its late then ... fi while ./its lunchtime do ... done
Jeśli użytkownik poda porę dnia nieznaną skryptowi należy wyświetlić komunikat o błędzie.
Skrypt który dodaje dyrektywę interpretera dla skryptów znalezionych we wskazanych katalogach. Do skryptów o rozszerzeniu .sh dodawane jest #!/bin/bash, do skryptow o rozszerzeniu .py ‘#!/usr/bin/env python’. Inne rodzaje skryptów są pomijane.
Przykład użycia:
./addshebang repository/scripts "/tmp/work in progress"
Jeśli plik już posiada dyrektywę interpretera, wypisz wiadomość do użytkownika i zignoruj plik.
Na pocieszenie¶
- Nobody really knows what the Bourne shell’s grammar is.
- Even examination of the source code is little help.
- – http://en.wikipedia.org/wiki/Tom_Duff