Funkcije
U ovoj lekciji naucicemo kako da organizujemo Bash skripte pomocu funkcija — jednog od najvaznijiih alata za pisanje citljivog i odrzivog koda.
Sta je funkcija?
Funkcija je minijaturna skripta unutar skripte. Jednom je definisete, a zatim je pozivate koliko god puta zelite. Dva glavna razloga za koriscenje:
- Izbegavanje ponavljanja — isti kod ne pisete vise puta
- Organizacija — skripta postaje pregledna, svaki zadatak ima svoje ime
Definisanje funkcije
Postoje dve sintakse:
# Preporučena forma:
ime_funkcije() {
echo "Hello iz funkcije"
}
# Alternativna (sa kljucnom recju function):
function ime_funkcije {
echo "Hello"
}
Obe forme su ispravne. Prva je kompaktnija i cesca u praksi.
Vazno: Funkcija mora biti definisana pre nego sto je pozovete. Bash cita skriptu odozgo nadole — ako pozovete funkciju pre njene definicije, dobicete gresku
command not found.
Pozivanje funkcije
Funkciju pozivate tako sto napisete njeno ime — bez zagrada:
#!/bin/bash
pozdravi() {
echo "Zdravo iz funkcije!"
}
pozdravi # Poziv — nema zagrada
pozdravi # Mozete pozivati vise puta
Izlaz:
Zdravo iz funkcije!
Zdravo iz funkcije!
Paznja: Za razliku od vecine programskih jezika, u Bash-u se funkcija ne poziva sa zagradama.
pozdravi()znaci definisanje, apozdraviznaci pozivanje.
Argumenti funkcije
Funkcije primaju argumente na isti nacin kao i skripte — kroz $1, $2, itd.:
#!/bin/bash
pozdravi() {
echo "Zdravo, $1!"
}
pozdravi Marko # Zdravo, Marko!
pozdravi Ana # Zdravo, Ana!
pozdravi "Jovana P" # Zdravo, Jovana P!
Sve specijalne varijable rade unutar funkcije:
| Varijabla | Znacenje unutar funkcije |
|---|---|
$1, $2, ... |
Argumenti prosledjeni funkciji |
$# |
Broj argumenata |
$@ |
Svi argumenti kao zasebne reci |
Primer sa vise argumenata i proverom:
#!/bin/bash
kopiraj_fajl() {
if [[ $# -ne 2 ]]; then
echo "Koriscenje: kopiraj_fajl <izvor> <odrediste>"
return 1
fi
cp "$1" "$2"
echo "Kopiran: $1 -> $2"
}
kopiraj_fajl dokument.txt /tmp/dokument.txt
kopiraj_fajl slika.png # Nedostaje argument — ispisuje uputstvo
Povratne vrednosti
Funkcije u Bash-u ne vracaju vrednosti kao u programiranju. Postoje dva nacina da prenesete rezultat:
Nacin 1: Echo + komandna supstitucija
Funkcija ispisuje rezultat, a pozivalac ga hvata pomocu $(...):
#!/bin/bash
saberi() {
echo $(($1 + $2))
}
zbir=$(saberi 3 5)
echo "3 + 5 = $zbir" # 3 + 5 = 8
rezultat=$(saberi 10 7)
echo "10 + 7 = $rezultat" # 10 + 7 = 17
Nacin 2: Exit kod sa return
return vraca broj od 0 do 255 — samo brojeve, ne stringove:
return 0— uspehreturn 1(ili bilo koji drugi broj) — greska
#!/bin/bash
proveri_broj() {
if [[ $1 -gt 0 ]]; then
return 0 # Uspeh — broj je pozitivan
else
return 1 # Greska — broj nije pozitivan
fi
}
proveri_broj 5
if [[ $? -eq 0 ]]; then
echo "Broj je pozitivan"
else
echo "Broj nije pozitivan"
fi
# Kompaktnija forma:
proveri_broj -3 || echo "Broj nije pozitivan"
Cesta greska:
return "greska"— ovo ne radi.returnprima samo cele brojeve 0-255. Za vracanje teksta koristite echo + komandnu supstituciju.
Lokalne varijable
Po defaultu, sve varijable u funkciji su globalne — menjaju vrednosti van funkcije. Ovo moze biti opasno:
#!/bin/bash
ime="Marko"
promena() {
ime="Ana" # Menja globalnu varijablu!
}
echo "$ime" # Marko
promena
echo "$ime" # Ana — neocekivano!
Resenje je kljucna rec local:
#!/bin/bash
ime="Marko"
promena() {
local ime="Ana" # Lokalna varijabla — ne dira globalnu
echo "Unutra: $ime"
}
echo "Pre: $ime" # Marko
promena # Unutra: Ana
echo "Posle: $ime" # Marko — globalna ostaje nepromenjena
Pravilo: Uvek koristite local za varijable unutar funkcija, osim ako namerno zelite da promenite globalnu vrednost.
Prakticna skripta
Uzmimo sve zajedno u realnijoj skripti:
#!/bin/bash
# backup.sh — skripta sa funkcijama
proveri_dir() {
if [[ ! -d "$1" ]]; then
echo "Greska: '$1' ne postoji ili nije direktorijum"
return 1
fi
return 0
}
napravi_backup() {
local izvor="$1"
local odrediste="$2"
local ime_backup="backup_$(date +%Y%m%d_%H%M%S)"
cp -r "$izvor" "$odrediste/$ime_backup"
echo "Backup napravljen: $odrediste/$ime_backup"
}
ispisi_velicinu() {
local dir="$1"
local velicina=$(du -sh "$dir" 2>/dev/null | cut -f1)
echo "Velicina '$dir': $velicina"
}
# Glavni deo skripte — funkcije vec definisane gore
IZVOR="/home/student/dokumenti"
ODREDISTE="/tmp"
proveri_dir "$IZVOR" || exit 1
proveri_dir "$ODREDISTE" || exit 1
napravi_backup "$IZVOR" "$ODREDISTE"
ispisi_velicinu "$IZVOR"
Sta cini ovu skriptu dobrom:
- Svaki zadatak ima ime (
proveri_dir,napravi_backup) - Koristimo
localza sve unutrasnje varijable - Proveravamo greske sa
return 1i|| exit 1 - Glavni deo skripte je kratak i citljiv
Ceste greske
Poziv pre definicije
#!/bin/bash
pozdravi # GRESKA: command not found
pozdravi() {
echo "Zdravo!"
}
Resenje: definicije funkcija staviti na vrh skripte, pozive na dno.
return sa stringom
proveri() {
return "greska" # GRESKA: ocekuje broj 0-255
}
Resenje: za vracanje teksta koristiti echo, za status koristiti return 0 / return 1.
Zaboravljeno local
#!/bin/bash
BROJAC=100
uvecaj() {
BROJAC=$((BROJAC + 1)) # Menja globalnu!
}
uvecaj
echo $BROJAC # 101 — ali da li smo to zeleli?
Resenje: koristiti local BROJAC unutar funkcije ako je promenljiva lokalna po prirodi.
Rezime
| Koncept | Sintaksa | Napomena |
|---|---|---|
| Definisanje | ime() { ... } |
Pre poziva! |
| Pozivanje | ime arg1 arg2 |
Bez zagrada |
| Argumenti | $1, $2, $#, $@ |
Kao u skripti |
| Povratna vrednost (tekst) | echo rezultat + $(ime) |
Najcesci nacin |
| Povratna vrednost (status) | return 0 / return 1 |
Samo 0-255 |
| Lokalna varijabla | local ime=vrednost |
Uvek koristiti |
U sledecim vezbama primenjujemo sve koncepte iz lekcija 01-05 — varijable, uslove, petlje i funkcije — u realnim skriptama.