Przykłady skryptów
-- Sebastian Pawlak
Przykłady skryptów
Przykładowe skrypty w BASHu. Najlepiej jest się uczyć analizując przykłady.
#!/bin/bash # Program odczytuje ze standardowego wejscia liczbe i sprawdza czy istnieje # odpowiedni argument skryptu. echo "Który argument (liczony od 1) ? " read i if [ $i -le $# -a $i -gt 0 ]; then # jesli i <= LICZBA_ARGUMENTOW i i > 0 echo -n "Argument nr $i istnieje i wynosi: " shift `expr $i - 1` echo $1 else echo "Argument nr $i nie istnieje" fi #!/bin/bash # # Skrypt kopiuje pliki z przyrostkiem ~ do katalogu BACKUP if [ -e "./BACKUP" -a ! -d "./BACKUP" ]; then # jezeli istnieje plik BACKUP # i nie jest katalogiem echo "BACKUP juz istnieje i nie jest katalogiem" exit fi if [ ! -d "./BACKUP" ]; then # jezli nie istnieje katalog BACKUP mkdir "./BACKUP" fi for i in *~; do echo "Kopiuję plik $i do katalogu BACKUP" cp "$i" "./BACKUP" done #!/bin/bash # Skrypt znajduje wszystkie pliki, ktore maja w swojej tresci swoja nazwe for i in *; do if [ -f "$i" ]; then # jezli to jest plik z=`cat $i | grep $i` # wypisanie pliku i poszukiwanie w jego tresci nazwy if [ -n "$z" ]; then # jezeli plik zawiera w swojej tresci swoja nazwe echo "Plik $i zawiera w swojej treści swoja nazwę" fi fi done #!/bin/bash # Skrypt wczytuje liczby i wypisuje max., min. i sumę if [ $# -lt 1 ]; then # jeżeli nie podano argumentów echo "Podaj nazwe pliku!" exit fi if [ ! -f "$1" ]; then # jeżeli podany jako argument plik nie istnieje echo "Plik $1 nie istnieje!" exit fi rozmiar=`cat "$1" | wc -l` # liczba wierszy w pliku if [ $rozmiar -eq 0 ]; then # jeżeli liczba wierszy w pliku wynosi 0 echo "Plik $1 jest pusty!" exit fi min=`cat "$1" | head -n 1` # na poczatku max i min równają się pierwszej max=$min # liczbie w pliku suma=0 # na początku suma wynosi 0 while [ $rozmiar -gt 0 ]; do # przeczytaj cały plik liczba=`cat "$1" | tail -n $rozmiar | head -n 1` # pojedynczy wiersz pliku if [ $liczba -gt $max ]; then # jeżeli liczba > niż dotychczasowy max max=$liczba # max staje się liczbą elif [ $liczba -lt $min ]; then # jeżeli liczba < niż dotychczasowy min min=$liczba # min staje się liczbą fi suma=$[ $suma + $liczba] # zwiększamy sumę o kolejną liczbę rozmiar=$[ $rozmiar - 1 ] # rozmiar pliku zmniejszamy o 1 done echo "Max. liczba $max" echo "Min. liczba $min" echo "Suma liczb $suma" #!/bin/bash # Procedura zamieniająca liczbę na jej reprezentację słowną procedura() { if [ $1 -lt 0 -a $1 -gt 99 ]; then echo "Liczba w nieprawidłowym zakresie!" exit fi case $1 in 10) echo "dziesięć" ;; 11) echo "jedenaście" ;; 12) echo "dwanaście" ;; 13) echo "trzynaście" ;; 14) echo "czternaście" ;; 15) echo "piętnaście" ;; 16) echo "szesnaście" ;; 17) echo "siedemnaście" ;; 18) echo "osiemnaście" ;; 19) echo "dziewiętnaście" ;; 2?) echo -n "dwadzieścia " ;; # -n -- nie przechodź do następnego wiersza 3?) echo -n "trzydzieści " ;; 4?) echo -n "czterdzieści " ;; 5?) echo -n "pięćdziesiąt " ;; 6?) echo -n "sześćdziesiąt " ;; 7?) echo -n "siedemdziesiąt " ;; 8?) echo -n "osiemdziesiąt " ;; 9?) echo -n "dziewięćdziesiąt " ;; esac if [ $i -lt 10 -o $i -gt 19 ]; then # jeżeli liczba < 10 i liczba > 19 case $1 in 0) echo "zero" ;; ?0) echo "" ;; *1) echo "jeden" ;; *2) echo "dwa" ;; *3) echo "trzy" ;; *4) echo "cztery" ;; *5) echo "pięć" ;; *6) echo "sześć" ;; *7) echo "siedem" ;; *8) echo "osiem" ;; *9) echo "dziewięć" ;; esac fi } # test procedury i=0 while [ $i -le 99 ]; do procedura $i i=$[ $i + 1 ]; done #!/bin/bash # Skrypt wyznacza n-tą liczbę Fibbonacciego # Program wyznacza liczbę metodą iteracyjną echo "Podaj numer liczby Fibbonacciego: " read i if [ $i -lt 1 ]; then echo "Wymagany numer większy od zera!" exit fi # 1 1 2 3 5 8 13 21 if [ $i -le 2 ]; then # dwie pierwsze liczby Fibbonacciego to jedynki echo "1"; exit fi i=$[ $i - 2 ] a=1 b=1 while [ $i -gt 0 ]; do # wykonuje pętlę jeżeli i > 0 c=$[ $a + $b ] a=$b b=$c i=$[ $i - 1 ] done echo $c #!/bin/bash # ./skr1 plik1 [ plik2 [ plikn ] ] # Program wypisuje naprzemiennie kolejne linie plikow podanych jako parametry. if [ $# -lt 1 ]; then echo 'brak parametru(ow) !' echo './skr1 plik1 [ plik2 [ plikn ] ]' exit fi lineNumber=1 pusty=0 # liczba plikow, ktore zostaly wyswietlone w calosci while [ $pusty -ne $# ]; do pusty=0 color=31 for i in $*; do color=$[ color + 1 ] if [ $lineNumber -gt `wc -l "$i" | awk '{print $1}'` ]; then pusty=$[ $pusty + 1 ] else echo -e "\\033[0;${color}m"`cat "$i" | head -n $lineNumber\ | tail -n 1`"\\033[0;37m" # wyswietla linie fi done lineNumber=$[ $lineNumber + 1 ] # kolejna linia pliku done #!/bin/bash # ./skr2 # Program przeszukuje drzewo katalogow i # usuwa pliki *.jpg mniejsze niz 5000bajtow - calkiem przydatny. rozmiar=0 for i in `find -type f -printf "%s:%p\n" | grep .jpg$`; do rozmiar=${i%:*} if [ $rozmiar -lt 5000 ]; then rm "${i#*:}" fi done #!/bin/bash # ./skr3 katalog1 [ katalog2 [ katalog3 ] ] # Program przeszukuje zadane katalogi i wyswietla informacje o tych # wszystkich plikach wewnatrz tych katalogow, ktore maja w swojej # tresci swoja nazwe. if [ $# -eq 0 ]; then echo 'brak parametru(ow) !' echo './skr3 katalog1 [ katalog2 [ katalog3 ] ]' exit fi while [ $# -gt 0 -a -d "$1" ]; do licznik=0 for i in `find $1 -type f -printf "%p " 2>/dev/null`; do # a tu bedzie sztuczka znana z C ... [ "`grep -l ${i##*/} $i 2>/dev/null`" ] && licznik=$[ $licznik + 1 ] done echo katalog $1 ma $licznik plikow, ktore maja w swojej tresci swoja nazwe shift done #!/bin/bash # ./skr4 katalog # Program przeszukuje zadany katalog i wyswietla informacje # o najwiekszym i najmniejszym pliku. if [ $# -lt 1 -o $# -gt 1 ]; then echo 'bledny parametr !' echo './skr4 katalog' exit fi katalog=$1 max=0 # taki sposob dzialania (poprzez nadanie malej i ogromnej min=99999999 # wartosci) nie jest zadowalajacy z punktu widzenia algorytmiki # ale spelnia wymogi praktyczne for i in `find $katalog -type f -printf '%s:%p\n' | sort -n -t ' '`; do w=${i%%:*} if [ $w -gt $max ]; then max=$w maxn="$i" fi if [ $w -lt $min ]; then min=$w minn="$i" fi echo "$i" done echo 'najwiekszy:' "$maxn" echo 'najmniejszy:' "$minn" #!/bin/bash # ./skr5 katalog plik # Program przeszukuje podany katalog w celu odnalezienia wszystkich # plikow 'plik' - wynik poszukiwan posortowany jest wedlug rozmiaru. find "$1" -type f -name "$2" -printf "%f %s\n" | sort -n -t' ' -k 2 #!/bin/bash # ./skr6 katalogZrodlowy katalogDocelowy # Program przeszukuje katalogZrodlowy i do kazdego pliku lub # katalogu tworzy w katalogDocelowym link o nazwie plikX (gdzie # X to kolejny numer) lub o nazwie katalogX dla katalogu. # UWAGA: nalezy podac sciezki bezwzgledne if [ $# -ne 2 ]; then echo 'bledne parametry !' echo './skr6 katalogZrodlowy katalogDocelowy' exit fi Nplk=0 Nktl=0 if [ ! -d "$2" ]; then mkdir "$2" fi for i in `find "$1"`; do if [ -f "$i" ]; then # plik ln -s "$i" "$2/plik$Nplk" Nplk=$[ $Nplk + 1 ] elif [ -d "$i" ]; then # katalog ln -s "$i" "$2/katalog$Nktl" Nktl=$[ $Nktl + 1 ] fi done #!/bin/bash # ./skr7 [-r] katalog # Program wyszukuje w zadanym katalogu linki, ktore na nic nie wskazuja. # Jezeli podano parametr `-r' to nastepuje proba usuniecia tych linkow. if [ $# -lt 1 -o $# -gt 2 ]; then echo 'zla liczba parametrow !' echo './skr7 [-r] katalog' exit fi if [ "$1" = '-r' ]; then katalog="$2" else katalog="$1" fi echo 'linki, ktore na nic nie wskazuja:' for i in `find "$katalog" -type l`; do if [ ! -f `readlink "$i"` -a ! -d `readlink "$i"` ]; then echo -n "$i -> `readlink "$i"`" if [ "$1" = '-r' ]; then rm -f "$i" 2>/dev/null if [ -L "$i" ]; then echo -n ' nie udalo sie skasowac' else echo -n ' udalo sie skasowac' fi fi echo fi done #!/bin/bash # ./skr8 katalog # Program dla kazdego podkatalogu zadanego katalogu wyswietla # sumaryczna wielkosc znajdujacych sie tam plikow. if [ $# -ne 1 ]; then echo 'zla liczba parametrow !' echo './skr8 katalog' exit fi for i in `find "$1" -type d`; do tmp=0 for j in `find "$i" -type f -printf "%s "`; do tmp=$[ $tmp + $j ] done echo "$i $tmp" done #!/bin/bash # ./skr9 plik rozmiar # Program dzieli plik na czesci po `rozmiar' wierszy. if [ $# -ne 2 ]; then echo 'bledna liczba parametrow !' exit fi rozmiar=`wc -l "$1"` rozmiar=${rozmiar% *} Nplk=0 while [ $[ $2 * $Nplk ] -lt $rozmiar ]; do cat "$1" | tail -n $[ $rozmiar - $2 * $Nplk ] | head -n $2 echo '-------' Nplk=$[ $Nplk + 1 ] done Zaliczeniowy skrypt eksternistyczny, SOP 1999/2000 Napisac skrypt flat, który spłaszcza strukturę katalogów w następujący sposób i korzysta z następujących założeń: * skrypt przyjmuje jedną opcję -l, po której następuje liczba oznaczająca ile poziomów w drzewie katalogów należy spłaszczyć. Liczba 0 oznacza brak spłaszczania, 1 bieżemy pod uwagę tylko podkatalogi, 2 podkatalogi i ich podkatalogi itd.. Brak opcji -l oznacza spłaszczanie całej struktury. * jeżeli skrypt dostanie (oprocz opcji -l) dwa parametry, to pierwszy parametr oznacza korzeń drzewa katalogów do spłaszczenia, a drugi katalog w jakim umieszczamy wynik. Jeżeli skrypt dostanie jeden parametr, to jest nim katalog wynikowy, a splaszczamy wszystko poczawszy od katalogu bieżącego. Odpowiednie przykłady wywołań: flat -l 10 katalog_spłaszczany tu_umieść_wynik flat tu_umieść_wynik W pierwszym przypadku spłaszczamy do 10 poziomów (jeżeli jest ich mniej to oczywiście wszystkie) drzewa o korzeniu katalog_spłaszczany i wynik umieszczamy w nowo zakładanym katalogu tu_umieść_wynik. W drugim przypadku spłaszczamy maksymalnie bieżący katalog, a wynik umieszczamy w tu_umieść_wynik. Możemy przyjąć, że wynik nie może być umieszczany wewnątrz katalog_splaszczany. * spłaszczenie wygląda następująco - dla każdego podkatalogu w drzewie katalog_spłaszczany, obojętnie na którym poziomie, w katalogu tu_umieść_wynik powstaje jeden katalog o takiej samej nazwie. (*) Jeżeli nazwy podkatalogów powtarzają się to należy poprzedzić je jednoznacznym prefiksem (np. ścieżka do niego). W każdym z tych nowo utworzonych katalogów zakładamy linki (dowiązania) symboliczne wskazujące na katalogi, które teraz są już w katalogu tu_umieść_wynik, a które pierwotnie były podkatalogami. Nazwy tych linków są takie jak nazwy podkatalogów w pierwotnym drzewie (patrz (*) - czyli w przypadku powtórzeń linki o starych nazwach wskazują na katalogi o nowych nazwach (z prefiksami)). * pliki pozostają w tych podkatalogach, w których były do tej pory. Przykład. Mamy drzewo: a / \ / \ b c / /|\ / / | \ d e f d Po wykonaniu spłaszczenia mamy: W katalogu tu_umieść_wynik znajduje się 7 podkatalogów o nazwach a, b, c, d, e, f, c_d (ta ostatnia nazwa to przykład). Podkatalog a zawiera wszystkie pliki z a (w drzewie pierwotnym) oraz linki: o nazwie b, wskazujący na b oraz o nazwie c wskazujący na c. Podkatalog b zawiera wszystkie pliki z b oraz linki o nazwie d, wskazujący na katalog d. Podkatalog c zawiera wszystkie pliki z c oraz linki e, f i d wskazujące odpowiednio na e, f i c_d. Podkatalogi e, f i c_d zawierają wszystkie pliki, które zawierały do tej pory e, f oraz d będące podkatalogami c. #!/bin/bash ######################################## # Zaliczeniowy skrypt # # eksternistyczny # # SOP 1999/2000 # ######################################## # Sebastian Pawlak # # nr albumu: s1222, grupa: 311 # ######################################## ### zmienne globalne ##################### katalogSplaszczany=`pwd` # aktualny katalog tuUmiescWynik=`pwd` maxGlebokoscSplaszczania=-1 # (-1) -> splaszcza cala strukture wynikPlus='' ### generowanie jednoznacznego prefiksu ### funkcja konwertuje napis zawierajacy sciezke (ze slash`ami) na napis ### zawierajacy te sciezke ale zamiast slash`ow beda znaki "_" ######################################################################### function konwertuj() { local s="$1" local d="$1"'x' local wynik=$wynikPlus while [ "$s" != "$d" ]; do d="${s%%/*}" # pierwszy wyraz (od poczatku do slash`a) s="${s#*/}" # wszystko oprocz pierwszego wyrazu wynik="$wynik$d" if [ "$s" != "$d" ]; then wynik=$wynik'_' fi done echo "$wynik" } ### glowna funkcja skryptu ; rekurencyjnie przeglada podkatalogi, tworzy ich ### kopie w katalogu "tuUmiescWynik" (uwzglednia powtarzajace sie nazwy), ### kopiuje pliki, tworzy linki ############################################################################# function splaszcz() { local katalog="$1" # katalog local aktualnaGlebokosc=$2 # glebokosc w drzewie rekurencyjnym local docelowy docelowy="$tuUmiescWynik/`konwertuj "$katalog"`" # kat. docelowy z prefiksem mkdir "$docelowy" 2>/dev/null # tworzy katalog w "tuUmiescWynik" echo "$katalog --> $docelowy" cp `find $katalog -type f -maxdepth 1` $docelowy 2>/dev/null # kopiow. plikow # "kopiowanie" linkow z odswiezaniem ich wskazan for i in `find $katalog -type l -maxdepth 1 -printf "%p\n"`; do linkdest=`find $katalog -name "${i##*/}" -type l -maxdepth 1 -printf "%l"` tmpKatalogBazowy=`pwd` cd "$katalog" # katalog z linkiem if [ -z "${linkdest%/*}" ]; then # katalog lub plik w korzeniu rzeczywisteWskazanie="/${linkdest##*/}" elif [ "${linkdest%/*}" != "$linkdest" ]; then # wskazanie na katalog tmpKatalog=`pwd` cd "${linkdest%/*}" rzeczywisteWskazanie="`pwd`/${linkdest##*/}" cd "$tmpKatalog" else # wskazanie na plik rzeczywisteWskazanie="`pwd`/${linkdest##*/}" fi cd "$tmpKatalogBazowy" tmpContain=`echo "$rzeczywisteWskazanie" | grep ^"$katalogSplaszczany"` if [ -n "$tmpContain" ]; then # link wskazuje na element w drzewie ln -s "../`konwertuj "$rzeczywisteWskazanie"`" "$docelowy/${i##*/}" else # link wskazuje poza drzewo splaszczane ln -s "$rzeczywisteWskazanie" "$docelowy/${i##*/}" fi done for k in `find $katalog -type d -mindepth 1 -maxdepth 1`; do if [ $maxGlebokoscSplaszczania -eq -1 \ -o $aktualnaGlebokosc -lt $maxGlebokoscSplaszczania ]; then splaszcz "$k" $[ $aktualnaGlebokosc + 1 ] # rekurencyjne wywolanie ln -s "$celLinka" "$docelowy" 2>/dev/null # tworzenie linka fi done celLinka="$docelowy" # nazwa aktualnego katalogu jest linkiem dla katalogu # polozonego plycej w zaglebieniu rekurencyjnym } ####################################### ### sterowanie przebiegiem programu ### ####################################### echo 'flat, s1222' ### identyfikacja parametrow przekazanych do skryptu ################################################### while [ $# -ne 0 ]; do if [ `expr "$1" = '-l'` -eq 1 ]; then shift maxGlebokoscSplaszczania=$1 else katalogSplaszczany=$tuUmiescWynik tuUmiescWynik="$1" fi shift done echo -n 'glebokosc splaszczania: ' if [ $maxGlebokoscSplaszczania -eq -1 ]; then echo 'cala struktura' else echo $maxGlebokoscSplaszczania fi if [ ! -d "$katalogSplaszczany" ]; then echo "katalog splaszczany nie istnieje" exit fi if [ -d "$tuUmiescWynik" ]; then echo "katalog docelowy juz istnieje" exit fi mkdir "$tuUmiescWynik" 2>/dev/null # tworzy "tuUmiescWynik" (jesli nie istnial) aktualnyKat=`pwd` cd "$katalogSplaszczany" katalogSplaszczany=`pwd` cd "$aktualnyKat" cd "$tuUmiescWynik" tuUmiescWynik=`pwd` cd "$aktualnyKat" tmpKt=`echo "$katalogSplaszczany" | grep '/'` if [ -z "$tmpKt" ]; then wynikPlus='_' fi echo ' katalog splaszczany:' $katalogSplaszczanyRoot echo ' katalog wynikowy:' $tuUmiescWynik if [ $maxGlebokoscSplaszczania -eq 0 ]; then echo "brak splaszczania" exit fi if [ "$katalogSplaszczany" = "$tuUmiescWynik" ]; then echo "katalog wynikowy i katalog splaszczany to ten sam katalog !" exit fi ### wywolanie glownej funkcji, ktora dokona splaszczenia struktury podkatalogow ############################################################################### splaszcz "$katalogSplaszczany" 0 # glowna funkcja echo 'koniec.'