POS/Predrok 2020

Izvor: SI Wiki
< ПОС
Datum izmene: 29. jun 2021. u 10:10; autor: KockaAdmiralac (razgovor | doprinosi) (-spoiler)
Pređi na navigaciju Pređi na pretragu

Predrok traje 120 minuta.

Zadatak 1

Postavka

(15p)

Izgled stabla
  • Napraviti lokalni git repozitorijum čije stablo istorije izgleda kao na slici desno.
  • Komentari svakog zapamćenog komita detaljno opisuju izmenu u repozitorijumu.
  • Redosled i komentari komita, kao i nazivi grana i pozicije referenci treba da budu kao na slici.
  • Umesto Student name potrebno je uneti svoje ime i prezime.

Napomena: Za prikaz stabla u gornjem obliku prekopirati sledeći kod u ~/.gitconfig fajl

[alias]
	lg1 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)' --all
	lg2 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)' --all
	lg = !"git lg1"

Rešenje

# napomena 'v' je alias za editor, koristite koji god želite da napravite promene

git init
git config user.name 'fedja'
v .gitignore # dodati "*~"
git add .gitignore
git commit -m '.gitignore created with line "*~"'
touch a.c
git add a.c
git commit -m 'a.c created(empty)'
touch b.c c.c
git add b.c c.c
git commit -m 'b.c and c.c created (both are empty)'
git checkout -b b1
v a.c # dodati line 1
v b.c # dodati line 2
v c.c # dodati line 1 i line 2
git add a.c b.c c.c # može i *.c
git commit -m "a.c - added 'line 1'; b.c - added 'line 2'; c.c - added two lines, 'line 1' and 'line 2'"
git checkout master
v a.c # dodati line 1
v b.c # dodati line 1
git add a.c b.c
git commit -m "a.c - added 'line 1'; b.c - added 'line 1'"
git merge b1
v b.c # izmeniti fajl u line 1 pa line 2
git add b.c c.c
git commit -m "merge branch 'b1'"
v a.c # dodati line 2
v c.c # dodati line 3
git add a.c c.c
git commit -m "a.c - added 'line 2'; c.c - added 'line 3'"
git checkout HEAD~3 # povratak tri grane unazad
git checkout -b b3
v c.c # dodati liniju 4
git commit c.c -m "c.c - added 'line 4'"
v a.c # dodati liniju 1
git commit a.c -m "a.c - added 'line 1';"
git checkout master
git merge b3
v a.c
v c.c
git add a.c c.c
git commit -m "merge branch 'b3' - a.c and c.c - changes kept from both branches;"
git checkout HEAD~4
git checkout -b b2
v b.c
git commit b.c -m "b.c - added 'line 2'"
git checkout master
git merge b2
v b.c
git add b.c
git commit -m "merge branch 'b2' - b.c - changes kept from both branches;"

Zadatak 2

Postavka

(15p) Napisati bash skriptu koja pokreće neki program. Da bi se program ispravno izvršavao potrebno je podesiti neke globalne promenljive i potrebno je prekopirati neke fajlove u direktorijum iz koga se program poziva. Direktorijum iz koga se program poziva se kreira po potrebi. Potrebno je omogućiti da se sistem vrati u stanje pre pokretanja skripte i pod tim se podrazumeva brisanje napravljenog direktorijuma i vraćanje globalnih promenljivih na vrednosti koje su imale pre pokretanja skripte. Argumenti skripte su:

  • Opcioni parametar sa argumentom -p. Putanja do programa koji se pokreće.
  • Opcioni parametar sa argumentom -d. Putanja do direktorijuma u kome treba pokrenuti program.
  • Opcioni parametar sa argumentom -v. Putanja do fajla koji sadrži parove reči, gde je svaki par u jednom redu. Prva reč u paru je ime promenljive, druga reč je vrednost koju ta promenljiva treba da ima prilikom pokretanja programa.
  • Opcioni parametar sa argumentom -f. Putanja do fajla koji sadrži putanje do fajlova koji moraju da se nađu u direktorijumu iz koga je program pozvan. Svaka putanja je u posebnom redu u fajlu.
  • Opcioni parametar -c. Ako postoji, skripta treba da vrati sistem u početno stanje.
  • Pozicioni argumenti se prosleđuju programu prilikom pokretanja. Broj pozicionih argumenata može biti nula ili veći.

Opcioni parametri -p, -d, -v i -f su obavezni. Prijaviti grešku u slučaju nekorektnih argumenata. Za smeštanje privremene fajlove[sic] se može koristiti direktoijum[sic] /tmp. Privremeni fajlovi moraju biti uklonjeni na kraju izvršavanja skripte.

Rešenje

#!/bin/bash

path=
dir=
vars=
files=
clean=
while getopts ":p:d:v:f:c" opt; do
    case $opt in
        p) path=$OPTARG
            ;;
        d) dir=$OPTARG
            ;;
        v) vars=$OPTARG
            ;;
        f) files=$OPTARG
            ;;
        c) clean=1
            ;;
        *) printf -- 'usage: ./skripta.sh -p path -d dir -v vars -f files [-c]\n'
           exit 1
            ;;
    esac
done
shift $(($OPTIND - 1))

# ako neki od flag-ova nije obezbeđen
if [ ! "$path" ] || [ ! "$dir" ] || [ ! "$vars" ] || [ ! "$files" ]; then
    printf -- 'nisu uneti obavezni parametri (-p, -d, -v, -f)\n'
    exit 2
fi

if [ ! -f "$path" ]; then
    printf -- 'program ne postoji\n'
    exit 3
fi

if [ ! -f "$vars" ]; then
    printf -- 'fajl sa parovima reči ne postoji\n'
    exit 4
fi

if [ ! -f "$files" ]; then
    printf -- 'fajl sa putanjama do fajlova ne postoji\n'
    exit 5
fi

# pravljenje direktorijuma
mkdir -p "$dir" # mkdir -p ne menja ništa ako direktorijum već postoji, alternativno [ ! -d "$dir" ] && mkdir "$dir"
# kopiranje programa u direktorijum
prog_name=${path##*/} # može i regexom: prog_name=$(echo $path | sed -n 's|.*/||p')
cp "$path" "$dir/$prog_name"

OLDIFS="$IFS" # čuvanje starog IFS-a

# pravljenje promenljivih
while IFS= read -r line; do # čitanje $vars liniju po liniju
    varname=$(echo $line | cut -d' ' -f1) # uzimanje prve reči u liniji
    varvalue=$(echo $line | cut -d' ' -f2) # uzimanje druge reči u liniji
    export "$varname"="$varvalue" # pravljenje promenljive
done < "$vars"
# promenljive će "nestati" iz sesije shell-a čim se završi skripta sem ako je ona pokrenuta sa `source ./skripta.sh`. što svakako nećete raditi.

# obezbeđivanje fajlova
temp_file=$(mktemp)
while IFS= read -r line; do
    file_name=${line##*/} # može i regexom: file_name=$(echo $line | sed -n 's|.*/||p')
    echo "$file_name" >> "$temp_file" # pamćenje svih fajlova koji su kopirani
    cp "$line" "$dir/$file_name" # kopiranje u željeni direktorijum
done < "$files"

# čišćenje ako smo izabrali -c
if [ "$clean" ]; then
    while IFS= read -r line; do # prolaženje kroz temp file i brisanje svih
        rm "$dir/$line"
    done < "$temp_file"
    rm "$temp_file"
    rm "$dir/$prog_name"
    rmdir --ignore-fail-on-non-empty # uklanjanje foldera samo ako je napravljen tek u programu
fi

# pokretanje programa
$dir/$prog_name

IFS="$OLDIFS" # restauracija IFS