ПОС/Лаб 3 2016

Извор: SI Wiki
< ПОС
Датум измене: 29. јун 2021. у 10:09; аутор: KockaAdmiralac (разговор | доприноси) (-spoiler)
(разл) ← Старија измена | Тренутна верзија (разл) | Новија измена → (разл)
Пређи на навигацију Пређи на претрагу

Лаб 3 се појављује у четвртом термину вежби.

Одрицање одговорности: аутору не ради виртуелна машина, па није хтео да ризикује са тестирањем неких од ових задатака. Параноичан је. Концепт је ту свакако.

Група 3

Задатак 1

Поставка

Написати скрипт који инсталира програме у систему. Низ програма се налази у фајлу, где у свакој линији стоји име програма (једна реч), име пакета помоћу кога се инсталира и име програма. Сви подаци у једној линији су одвојени једним бланко знаком. За сваки програм исталирати[sic] одговарајући пакет. Не сме да се приказује било какав испис у току инсталације нити да се пита корисник несто[sic].

Опција -f са параметром - име фајла из кога се читају сајтови. Опција је обавезна, у супротном је грешка.
Опција -i - означава да треба прекинути рад ако се наиђе на програм који је већ инсталиран. Ако опције нема прескочити проблематичан програм.
Ставка Поени
Читање аргумената 3
Инсталација 3
Обрада фајла 3
Исправна скрипта 5
Сума 14

Решење

Одрађен је само део читања аргумената јер задатак није довољно јасан без улазног фајла. Није сигурно на који начин се покрећe инсталација, чак је и двосмислен формат у којем су исписани подаци.

#!/bin/bash

infile=
interrupt=
while getopts ":f:i" opt
do
    case $opt in
        f) infile=$OPTARG
            ;;
        i) interrupt=1
            ;;
        *) printf -- 'korišćenje:\n./skripta.sh -f fajl [-i]\n'
            exit 1
            ;;
    esac
done

if [ -z "$infile" ]; then
    printf -- "-f je obavezan flag\n"
    exit 2
fi

if [ ! -f "$infile" ]; then
    printf -- "nepostojeći fajl\n"
    exit 3
fi

while IFS= read -r line
do
    echo $line
done < "$infile"


Група 4

Задатак 1

Поставка

Написати скрипт који подешава аутоматско монтирање партицији[sic] приликом стартовања система. Низ партиција се налази у фајлу, где у свакој линији стоји путања до партиције (нпр. /dev/sda4), фајл систем на пратицији[sic] и фолдер у који треба да се монтира. Сви подаци у једној линији су одвојени једним бланко знаком. За сваку партицију треба подесити аутоматско монтирање ако већ не постоји. Скрипта има следеће аргументе:

Позициони параметар - име фајла из кога се читају налози
Опција -o са параметром - означава да параметар треба да буду подешавања приликом монтирања. Ако опције нема, подешавања за монтирање треба да буду иста као код партиције која је монтирана у home директоријум.
Опција -b - ако постоји означава да треба направити backup копију конфигурационог фајла пре промене.
Ставка Поени
Читање аргумената 3
Конфигурисање монтирања 3
Обрада фајла 3
Исправна скрипта 5
Сума 14

Решење

#!/bin/bash

backup=
options="defaults"
while getopts ":o:b" opt
do
    case $opt in
    o) options="$OPTARG"
        ;;
    b) backup=1
        ;;
    *) printf -- 'korišćenje:\n./skripta.sh [-b] [-o opcije]'
        exit 1
        ;;
    esac
done
shift $(( $OPTIND - 1 ))
infile=$1

if [ -z $infile ]; then
    printf -- 'pozicioni parametar je obavezan\n'
    exit 2
fi

if [ ! -f $infile ]; then
    printf -- 'ne postoji fajl\n'
    exit 3
fi

destfile="/etc/fstab"
[ $backup ] &&
    sudo cp "$destfile" "/etc/fstab.old" && 
    printf -- "backup napravljen\n"

while IFS= read -r line
do
    particija=$(cut -d' ' -f1 <<< "$line")
    fs=$(cut -d' ' -f2 <<< $line) # nije poznato kako je formatiran filesystem u originalu, ali ako ne postoji, potrebno je da ima vodeći UUID=.
    dest=$(cut -d' ' -f3 <<< $line)

    ismounted="$(grep "$fs" "$destfile")" # ako fajlsistem već postoji u /etc/fstab, ne ubacuje se
    fstype=$(blkid "$particija" |
        sed -E 's/.*TYPE="(\w+)".*/\1/')
    dump=0
    fsck=0

    if [ -z "$ismounted" ]; then
        sudo mkdir -p $dest # pravljenje destinacije mount-ovanja ako ne postoji
        printf -- "$particija\t$fs\t$dest\t$fstype\t$options\t$dump\t$fsck\n" >> $destfile
    fi

done < "$infile"


Група 5

Задатак 1

Поставка

Написати скрипт који прави копију података са неке партиције. Партиције које треба клонирати се налазе у фајлу који у свакој линији садржи име партиције коју треба клонирати (нпр. /dev/sda6) и величину блока приликом копирања (нпр. 64K). Фајл у који се снима партиција треба да буде gzip-ован и треба да има име по формату <диск>_<број партиције>_<датум>.img.gz (нпр. sda_6_06_04_2016.img.gz). Скрипта има следеће аргументе:

Позициони параметар - фајл са листом партиција за копирање
Опција -a са параметром која одређује у којем директоријуму треба да се налазе копије. Опција мора да постоји, у супротном је грешка.
Опција -e - игнорисање грешака приликом копирања. Ако не постоји грешке се не игноришу.
Ставка Поени
Читање аргумената 3
Копирање партиције 3
Команде за обраду фајла 3
Исправна скрипта 5
Сума 14

Решење

#!/bin/bash
set -e

copydir=
infile=
ignoreErrors=
while getopts ":a:e" opt
do
    case $opt in
    a) copydir=$OPTARG # obavezan
        ;;
    e) ignoreErrors=1
        ;;
    *) printf -- 'korišćenje:\n./skripta.sh -a fajl [-e]\n'
        exit 1
        ;;
    esac
done
shift $(( $OPTIND - 1 ))
infile=$1

if [ -z "$copydir" ]; then
    printf -- '-a je obavezan flag\n'
    exit 2
fi

if [ ! -d "$copydir" ]; then
    printf -- 'ne postoji direktorijum\n'
    exit 3
fi

if [ -z "$infile" ]; then
    printf -- 'pozicioni parametar je obavezan\n'
    exit 4
fi

if [ ! -f "$infile" ]; then
    printf -- 'ne postoji fajl\n'
    exit 5
fi

while IFS= read -r line
do
    device=$(cut -d' ' -f1 <<< "$line")
    blocks=$(cut -d' ' -f2 <<< "$line")

    of=$(
    printf -- "%s_%s_%s.img.gz" \
        "$(sed -E 's|/dev/(sd\w+)[0-9]+|\1|' <<< $device)" \
        "$(sed -E 's|/dev/\w+([0-9]+)|\1|' <<< $device)" \
        "$(date "+%d_%m_%Y")"
    )
    if [ $ignoreErrors ]; then
        dd conv=noerror bs="$blocks" if="$device" | 
            gzip -c > "$copydir/$of"
    else
        dd bs="$blocks" if="$device" | 
            gzip -c > "$copydir/$of"
    fi

done < "$infile"


Група 6

Задатак 1

Поставка

Написати скрипт који додаје команде које треба да се изврше приликом стартовања конзоле за неког корисника. Команде које се додају се налазе у фајлу и одвојене су знаком ;. Сваку команду треба додати у конфигурациони фајл на крај и свака команда треба да буде у посебној линији. Ако команда садржи апсолутну путању ка директоријуму који се налази у /home директоријуму ту путању треба изменити да показује на директорјум[sic] корисника (нпр. корисник је pos а путања је /home/pera/zdera/pljeskavica, резултат треба да буде /home/pos/zdera/pljeskavica). Скрипта има следеће аргументе:

Опција -l са параметром - дефинише фајл у који треба додати информације о томе колико је команди додато и колико је промена директоријума извршено. Ако не постоји, не треба нигде уписати те податке.
Опција -f са параметром која дефинише који фајл садржи команде за доделу и опција је обавезна, у супротном је грешка.
Позициони параметар је корисник за кога се обрада ради и обавезан је, у супротном је грешка.
Ставка Поени
Читање аргумената 3
Мењање конфигурационог фајла 3
Обрада фајла 3
Исправна скрипта 5
Сума 14

Решење

#!/bin/bash
set -e # izlazak ako neka komanda ne valja

statFile=
infile=
korisnik=

# čitanje argumenata
while getopts ":l:f:" opt
do
    case $opt in
    l) statFile=$OPTARG
        ;;
    f) infile=$OPTARG # obavezan
        ;;
    *) printf '%b%s' "korišćenje:\n./skripta.sh -f fajl [-l fajl] korisnik\n"
        exit 1
        ;;
    esac
done
shift $(( $OPTIND - 1 ))
korisnik="$1" # korisnik je jedna reč

if [ -z "$infile" ]; then
    printf -- "-f je obavezan flag\n"
    exit 2
fi

if [ ! -f "$infile" ]; then
    printf -- 'nepostojeći fajl\n'
    exit 3
fi

if [ -z "$korisnik" ]; then
    printf -- 'korisnik je obavezan\n'
    exit 4
fi

if [ -d "/home/$korisnik" ]; then
    printf -- 'korisnik ne postoji\n'
    exit 5
fi

[ ! -z "$statFile" ] && [ ! -f "$statFile" ] && statFile=

# menjanje konfiguracionog fajla
destfile="/home/$korisnik/.profile"
tempfile=$(mktemp)

while IFS= read -r line
do
    printf -- "$line\n" |
        sed -E "s|/home/[[:alnum:]_-]+|/home/$korisnik|g; \
        s/; ?/\n/g;" |
        grep -v "^\s*$" |
        tee -a "$destfile" "$tempfile" >/dev/null

done < "$infile"

[ ! -z "$statFile" ] && 
    printf -- 'komandi ubačeno: %s\n' \
        $(wc -l "$tempfile" |
            cut -d' ' -f1) > "$statFile" &&
    printf -- "promena direktorijuma: %s\n" \
        $(grep "/home/[[:alnum:]_-]\+" "$infile" |
            grep -v "/home/$korisnik[^[:alnum:]]" | 
            wc -l) >> "$statFile"

rm "$tempfile"