POS/Lab 3 2016

Izvor: SI Wiki
Pređi na navigaciju Pređi na pretragu

Lab 3 se pojavljuje u četvrtom terminu vežbi.

Odricanje odgovornosti: autoru ne radi virtuelna mašina, pa nije hteo da rizikuje sa testiranjem nekih od ovih zadataka. Paranoičan je. Koncept je tu svakako.

Grupa 3

Zadatak 1

Postavka

Napisati skript koji instalira programe u sistemu. Niz programa se nalazi u fajlu, gde u svakoj liniji stoji ime programa (jedna reč), ime paketa pomoću koga se instalira i ime programa. Svi podaci u jednoj liniji su odvojeni jednim blanko znakom. Za svaki program istalirati[sic] odgovarajući paket. Ne sme da se prikazuje bilo kakav ispis u toku instalacije niti da se pita korisnik nesto[sic].

Opcija -f sa parametrom - ime fajla iz koga se čitaju sajtovi. Opcija je obavezna, u suprotnom je greška.
Opcija -i - označava da treba prekinuti rad ako se naiđe na program koji je već instaliran. Ako opcije nema preskočiti problematičan program.
Stavka Poeni
Čitanje argumenata 3
Instalacija 3
Obrada fajla 3
Ispravna skripta 5
Suma 14

Rešenje

Odrađen je samo deo čitanja argumenata jer zadatak nije dovoljno jasan bez ulaznog fajla. Nije sigurno na koji način se pokreće instalacija, čak je i dvosmislen format u kojem su ispisani podaci.

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


Grupa 4

Zadatak 1

Postavka

Napisati skript koji podešava automatsko montiranje particiji[sic] prilikom startovanja sistema. Niz particija se nalazi u fajlu, gde u svakoj liniji stoji putanja do particije (npr. /dev/sda4), fajl sistem na praticiji[sic] i folder u koji treba da se montira. Svi podaci u jednoj liniji su odvojeni jednim blanko znakom. Za svaku particiju treba podesiti automatsko montiranje ako već ne postoji. Skripta ima sledeće argumente:

Pozicioni parametar - ime fajla iz koga se čitaju nalozi
Opcija -o sa parametrom - označava da parametar treba da budu podešavanja prilikom montiranja. Ako opcije nema, podešavanja za montiranje treba da budu ista kao kod particije koja je montirana u home direktorijum.
Opcija -b - ako postoji označava da treba napraviti backup kopiju konfiguracionog fajla pre promene.
Stavka Poeni
Čitanje argumenata 3
Konfigurisanje montiranja 3
Obrada fajla 3
Ispravna skripta 5
Suma 14

Rešenje

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


Grupa 5

Zadatak 1

Postavka

Napisati skript koji pravi kopiju podataka sa neke particije. Particije koje treba klonirati se nalaze u fajlu koji u svakoj liniji sadrži ime particije koju treba klonirati (npr. /dev/sda6) i veličinu bloka prilikom kopiranja (npr. 64K). Fajl u koji se snima particija treba da bude gzip-ovan i treba da ima ime po formatu <disk>_<broj particije>_<datum>.img.gz (npr. sda_6_06_04_2016.img.gz). Skripta ima sledeće argumente:

Pozicioni parametar - fajl sa listom particija za kopiranje
Opcija -a sa parametrom koja određuje u kojem direktorijumu treba da se nalaze kopije. Opcija mora da postoji, u suprotnom je greška.
Opcija -e - ignorisanje grešaka prilikom kopiranja. Ako ne postoji greške se ne ignorišu.
Stavka Poeni
Čitanje argumenata 3
Kopiranje particije 3
Komande za obradu fajla 3
Ispravna skripta 5
Suma 14

Rešenje

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


Grupa 6

Zadatak 1

Postavka

Napisati skript koji dodaje komande koje treba da se izvrše prilikom startovanja konzole za nekog korisnika. Komande koje se dodaju se nalaze u fajlu i odvojene su znakom ;. Svaku komandu treba dodati u konfiguracioni fajl na kraj i svaka komanda treba da bude u posebnoj liniji. Ako komanda sadrži apsolutnu putanju ka direktorijumu koji se nalazi u /home direktorijumu tu putanju treba izmeniti da pokazuje na direktorjum[sic] korisnika (npr. korisnik je pos a putanja je /home/pera/zdera/pljeskavica, rezultat treba da bude /home/pos/zdera/pljeskavica). Skripta ima sledeće argumente:

Opcija -l sa parametrom - definiše fajl u koji treba dodati informacije o tome koliko je komandi dodato i koliko je promena direktorijuma izvršeno. Ako ne postoji, ne treba nigde upisati te podatke.
Opcija -f sa parametrom koja definiše koji fajl sadrži komande za dodelu i opcija je obavezna, u suprotnom je greška.
Pozicioni parametar je korisnik za koga se obrada radi i obavezan je, u suprotnom je greška.
Stavka Poeni
Čitanje argumenata 3
Menjanje konfiguracionog fajla 3
Obrada fajla 3
Ispravna skripta 5
Suma 14

Rešenje

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