Preusmeravanje
Cilj učenja: Nakon ove lekcije znaš da koristiš operatore >, >>, <, 2>, 2>&1 i /dev/null da preusmeravaš standardne tokove u fajlove i obratno.
Šta je preusmeravanje?
Podrazumevano, stdout ide na ekran a stdin dolazi sa tastature. Preusmeravanje (redirection) menja te podrazumevane veze — kaže shellu da tok poveže sa fajlom umesto sa terminalom.
Preusmeravanje se piše pored komande, ne unutar nje:
komanda > fajl.txt
Shell to interpretira: "pokreni komandu, ali njen stdout preusmeri u fajl.txt".
> — prepiši fajl (stdout)
Operator > preusmeri stdout u fajl. Ako fajl postoji, briše ga i piše iznova. Ako ne postoji, kreira ga.
echo "Zdravo" > pozdrav.txt
Fajl pozdrav.txt sada sadrži jednu liniju: Zdravo.
ls -l /etc > lista.txt
Sav izlaz od ls -l /etc upisuje se u lista.txt — na ekranu se ništa ne prikazuje.
date > vreme.txt
cat vreme.txt
ned apr 13 12:34:56 UTC 2025
Upozorenje:
>bezuslovno briše sadržaj fajla ako postoji. Komanda> fajl.txt(bez ičega ispred) prazni fajl. Budi oprezan sa važnim fajlovima.
>> — dodaj na kraj fajla (stdout)
Operator >> preusmeri stdout u fajl, ali dodaje na kraj umesto da briše.
echo "Prva linija" > dnevnik.txt
echo "Druga linija" >> dnevnik.txt
echo "Treca linija" >> dnevnik.txt
cat dnevnik.txt
Prva linija
Druga linija
Treca linija
Korisno za logovanje i akumuliranje rezultata:
date >> log.txt # dodaj trenutno vreme u log
echo "Backup gotov" >> log.txt
< — ulaz iz fajla (stdin)
Operator < preusmeri stdin iz fajla umesto sa tastature.
sort < lista.txt
sort čita linije iz lista.txt (umesto da čeka na tastaturski unos) i ispisuje ih sortirano.
wc -l < dokument.txt
Broji linije u fajlu. (Ovo je ekvivalentno sa wc -l dokument.txt, ali < eksplicitno pokazuje odakle dolazi stdin.)
2> — prepiši fajl (stderr)
Operator 2> preusmeri stderr (deskriptor 2) u fajl. stdout i dalje ide na ekran.
ls /nepostoji 2> greske.txt
Poruka greške ide u greske.txt, a na ekranu se ništa ne ispisuje.
cat greske.txt
ls: cannot access '/nepostoji': No such file or directory
Korisno kada pokrećeš skriptu i hoćeš da sačuvaš greške radi analize:
./moja-skripta.sh 2> errors.log
Sve greške idu u errors.log, a normalan izlaz vidis na ekranu.
2>> — dodaj stderr na kraj fajla
Kao >> ali za stderr:
./skripta.sh 2>> errors.log
2>&1 — preusmeri stderr na stdout
Sintaksa 2>&1 kaže: "deskriptor 2 (stderr) preusmeri na isto mesto gde ide deskriptor 1 (stdout)".
ls /tmp /nepostoji > sve.txt 2>&1
I normalan izlaz i greške idu u sve.txt. Na ekranu se ništa ne prikazuje.
Redosled je važan! Uvek piši > fajl 2>&1, a ne 2>&1 > fajl:
# Ispravno: oboje u fajl
komanda > log.txt 2>&1
# Pogresno: stderr ide na ekran, samo stdout u fajl
komanda 2>&1 > log.txt
Zašto? Shell obrađuje preusmeravanja sleva nadesno. U ispravnom redosledu: prvo se stdout vezuje za log.txt, pa se stderr vezuje za "gde god sad ide stdout" (tj. log.txt). U pogrešnom redosledu: stderr se vezuje za "gde god sad ide stdout" (terminal), pa tek onda stdout ide u log.txt — ali stderr je već vezan za terminal.
Moderan bash nudi i skraćenu sintaksu &>:
ls /tmp /nepostoji &> sve.txt # isto kao > sve.txt 2>&1
/dev/null — crna rupa
/dev/null je specijalni fajl koji odbacuje sve što mu se upiše i daje prazan izlaz ako se čita. Korisno kada ne mariš za određeni tok:
# Ignoriši greške — prikaži samo uspešan izlaz
ls /tmp /nepostoji 2> /dev/null
# Ignoriši normalan izlaz — prikaži samo greške
ls /tmp /nepostoji > /dev/null
# Ignoriši sve — samo pokreni, ne prikazuj ništa
ls /tmp /nepostoji &> /dev/null
Česta upotreba u skriptama: pokretanje komande samo zbog efekta (npr. provera da li nešto postoji), bez štampanja izlaza.
Kombinovanje preusmeravanja
Možeš kombinovati više preusmeravanja u jednoj komandi:
komanda < ulaz.txt > izlaz.txt 2> greske.txt
- stdin: čita iz
ulaz.txt - stdout: upisuje u
izlaz.txt - stderr: upisuje u
greske.txt
Pregled operatora
| Operator | Tok | Dejstvo |
|---|---|---|
> |
stdout (1) | Prepiši fajl |
>> |
stdout (1) | Dodaj na kraj fajla |
< |
stdin (0) | Ulaz iz fajla |
2> |
stderr (2) | Prepiši fajl greškama |
2>> |
stderr (2) | Dodaj greške na kraj fajla |
2>&1 |
stderr → stdout | Spoji stderr sa stdout |
&> |
stdout + stderr | Prepiši fajl (oba toka) |
&>> |
stdout + stderr | Dodaj oba toka na kraj fajla |
> /dev/null |
stdout | Odbaci izlaz |
2> /dev/null |
stderr | Odbaci greške |