Zestaw pośredni 1

Materiały do zajęć z Systemów operacyjnych prowadzonych na Wydziale Matematyki i Informatyki Uniwersytetu im. Adama Mickiewicza w Poznaniu.

« Wróć do spisu materiałów

Ćwiczenia

Napisz skrypt, który wypisze przekazane argumenty w odwrotnej kolejności.

Zobacz odpowiedź

#!/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.

Zobacz odpowiedź

#!/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.

Zobacz odpowiedź

#!/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ć.

Zobacz odpowiedź

#!/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.

Zobacz odpowiedź

#!/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.

Zobacz odpowiedź

#!/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).

Zobacz odpowiedź

#!/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.

Zobacz odpowiedź

#!/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.

Zobacz odpowiedź

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ę.