Ćwiczenia
Napisz skrypt, który wypisze przekazane argumenty w odwrotnej kolejności.
#!/bin/bash
if [ $# -eq 0 ]; then exit 1; fi
for ((i=$#;i>0;i--))
do
eval echo -n "\$$i "
done
echo
#!/bin/bash
if [ $# -eq 0 ]; then exit 1; fi
for i in `eval echo {$#..1}`
do
eval echo -n "\$$i "
done
echo
#!/bin/bash
if [ $# -eq 0 ]; then exit 1; fi
while [ $# -ge 1 ]
do
wynik="$1 $wynik"
shift
done
echo $wynik
W katalogu http://bprzybylski.github.io/DSOP/files/suma znajduje się 100 plików o nazwach od 001.txt
do 100.txt
, zawierających po jednej liczbie z przedziału od 0 do 100. Napisz skrypt, który wypisze sumę liczb z tych plików. Aby pobrać zawartość pliku ze zdalnego serwera, wykorzystaj program curl
.
#!/bin/bash
suma=0
for i in {001..100}.txt
do
k=`curl http://bprzybylski.github.io/dsop/files/suma/$i 2> /dev/null`
suma=$((suma+k))
done
echo $suma
Ten skrypt będzie się wykonywał bardzo długo. Pobranie stu plików wymaga dużo komunikacji między serwerem a klientem, nawet jeśli pliki nie są zbyt duże.
Napisz skrypt, który przyjmuje jako argumenty rozszerzenie źródłowe i docelowe, a następnie zmienia rozszerzenia plików w bieżącym katalogu zgodnie z przekazanymi parametrami i wypisuje raport zmian na ekranie. Przykładowe wywołanie:
$ ./rozszerzenia.sh log txt
plik.log => plik.txt
raport.log => raport.txt
Wykorzystaj program basename
. Załóż, że istnieje co najmniej jeden plik źródłowy.
#!/bin/bash
# $1 - rozszerzenie zrodlowe
# $2 - rozszerzenie docelowe
for f in *.$1
do
basename=`basename "$f" .$1`
mv "$f" "$basename".$2
echo "$f => $basename.$2"
done
Rozszerz skrypt z poprzedniego ćwiczenia tak, aby w momencie, gdy plik docelowy istnieje, pytał użytkownika czy chce go zastąpić.
#!/bin/bash
# $1 - rozszerzenie zrodlowe
# $2 - rozszerzenie docelowe
for f in *.$1
do
basename=`basename "$f" .$1`
if [ -f "$basename.$2" ]
then
echo -n "Plik $basename.$2 istnieje.
Czy chcesz go zastapic? [T] "
read t
if [ "$t" = "T" ]
then
mv "$f" "$basename.$2"
echo "$f => $basename.$2"
fi
else
mv "$f" "$basename.$2"
echo "$f => $basename.$2"
fi
done
Pseudozmienna $RANDOM
zwraca losową wartość całkowitą dodatnią za każdym razem, gdy jest wywoływana. Wykorzystaj ją, aby napisać skrypt, w którym użytkownik zgaduje wylosowaną liczbę z przedziału od 100 do 1000. Skrypt powinien naprowadzać użytkownika na prawidłowe rozwiązanie, wypisując komunikaty "Więcej" lub "Mniej", w zależności od wprowadzonej liczby. Gdy użytkownik wprowadzi dobry wynik, skrypt powinien zakończyć działanie.
#!/bin/bash
liczba=$((100+($RANDOM%901)))
echo -n "Podaj liczbe: "
read n
while [ $n -ne $liczba ]
do
if [ $n -lt $liczba ]
then
echo "Wiecej"
elif [ $n -gt $liczba ]
then
echo "Mniej"
fi
echo -n "Sprobuj jeszcze raz: "
read n
done
Zaimplementuj algorytm Euklidesa (z dzieleniem) wyznaczania NWD dwóch liczb dodatnich. Skrypt powinien pobierać dane ze standardowego wejścia, w którym każdy wiersz zbudowany jest z dwóch liczb oddzielonych znakiem odstępu.
#!/bin/bash
while read a b
do
r=$((a%b))
while [ $r -ne 0 ]
do
a=$b b=$r r=$((a%b))
done
echo $b
done
Napisz skrypt, który przekształca przekazane liczby dziesiętne do postaci dwójkowej. Skrypt powinien obsługiwać zarówno więcej niż jeden argument, jak i (jeśli nie przekazano żadnych argumentów) liczby przekazywane na standardowe wejście (po jednej w linii).
#!/bin/bash
if [ $# -eq 0 ]
then
while read l
do
arg=$arg" "$l
done
fi
for l in $*$arg
do
str=""
if ([ "$l" -eq "$l" ] && [ $l -gt 0 ]) &> /dev/null
then
while [ $l -gt 0 ]
do
str="$((l%2))$str"
l=$((l/2))
done
echo $str
else
echo "Argumentem powinna byc liczba dodatnia" 1>&2
fi
done
Zmodyfikuj skrypt z poprzedniego ćwiczenia tak, aby pierwszy argument określał zawsze podstawę systemu liczbowego (z przedziału od 2 do 10).
Zmodyfikuj skrypt z poprzedniego ćwiczenia tak, aby przetwarzał liczby zaraz po ich wczytaniu (nie czekając na koniec wejścia). Wykorzystaj funkcje powłoki Bash.
Plik dist.male.first zawiera opublikowane przez Amerykańskie Biuro Cenzusowe statystyki dotyczące częstości występowania imion wśród obywateli USA płci męskiej (stan na rok 1990). Kolumny oznaczają kolejno: imię, częstość (w procentach), częstość (kumulatywna, w procentach) i miejsce w rankingu. Napisz skrypt, który wypisze na wyjściu tę listę w postaci tabeli w języku HTML
, posortowanej alfabetycznie według imion. W tabeli uwzględnij kolumny: imię, częstość oraz miejsce w rankingu.
Zmodyfikuj skrypt z poprzedniego ćwiczenia tak, aby przyjmował dwa argumenty: nazwę przetwarzanego pliku oraz nazwę docelowego pliku HTML
. Następnie wygeneruj tabelę w języku HTML
dla statystyk częstości występowania imion żeńskich. Wykorzystaj plik dist.female.first.
#!/bin/bash
echo "<table>" > $2
cat $1 | sort -k 1 | while read line
do
line=($line)
echo "<tr><td>${line[0]}</td><td>${line[1]}</td>
<td>${line[3]}</td></tr>"
done >> $2
echo "</table>" >> $2
Zmodyfikuj skrypt z poprzedniego ćwiczenia tak, aby imiona nie były zapisane drukowanymi literami, a w postaci klasycznej, tj. pierwsza litera wielka, pozostałe małe.
Zainspiruj się następującym fragmentem kodu:
${name:0:1}$(tr '[:upper:]' '[:lower:]' <<< ${name:1})
Praktyczne ćwiczenia
Ten paragraf zawiera kilka ćwiczeń, dzięki którym przetestujesz swoje umiejętności na praktycznych problemach, z którymi możesz się spotkać w przyszłej pracy zawodowej (lub nie).
Plik access_log.log zawiera przykładowe dane zapisane na dysku przez serwer Apache.
- Wyświetl adresy wszystkich hostów, które próbowały pobrać z serwera plik
/dccstats/stats-hashes.1week.png
. - Przerób rozwiązanie z poprzedniego punktu na użyteczny i uniwersalny skrypt powłoki Bash.
Napisz skrypt powłoki Bash, który będzie można uruchamiać cyklicznie za pomocą oprogramowania cron
. Skrypt powinien sprawdzać, czy na którymś z dysków jest mniej niż X
procent wolnego miejsca, a jeśli tak, to powinien wysłać e-mail z ostrzeżeniem na wskazany adres. Postaraj się, aby skrypt był jak najbardziej uniwersalny.
Napisz skrypt, który wykonuje kopię zapasową wszystkich tych plików ze wskazanych katalogów, które zostały utworzone lub zmodyfikowane w ciągu 7 dni od chwili uruchomienia skryptu. Skrypt powinien generować archiwum tar.gz
, które następnie powinno być wysyłane (dowolną metodą) na inną maszynę.