Standardni tokovi
Cilj učenja: Nakon ove lekcije razumeš šta su stdin, stdout i stderr, koje deskriptore nose, odakle dolaze i kuda idu — i zašto je to temelj svakog preusmeravanja i pajpa.
Sve je tok podataka
Kada pokreneš komandu u terminalu, operativni sistem automatski otvara tri komunikaciona kanala između tog programa i okoline. Ovi kanali se zovu standardni tokovi (standard streams).
Svaki tok ima broj — deskriptor fajla (file descriptor, skr. fd; zamisli kao broj kanala — kanal 0 ulaz, kanal 1 izlaz, kanal 2 greske):
| Deskriptor | Ime | Skraćenica | Podrazumevani izvor/odredište |
|---|---|---|---|
0 |
Standard Input | stdin | Tastatura |
1 |
Standard Output | stdout | Ekran (terminal) |
2 |
Standard Error | stderr | Ekran (terminal) |
Ključna napomena: stdout i stderr oba idu na ekran po podrazumevanim podešavanjima, ali su to dva odvojena toka. Ovo će biti važno kada ih budeš preusmeravao odvojeno.
stdin — ulaz (deskriptor 0)
stdin je tok odakle program čita podatke. Podrazumevano, stdin dolazi sa tastature — sve što kucaš.
cat
Ako pokreneš cat bez argumenata, čeka na stdin. Sve što ukucaš, ispiše nazad. Pritisni Ctrl+D da signaliziraš kraj ulaza (EOF — End Of File).
Mnoge komande čitaju sa stdin ako im ne daš fajl kao argument:
sort # čeka unos sa tastature, sortira ga kada stigne EOF
wc -l # broji linije primljene na stdin
grep "reč" # filtrira linije primljene na stdin
stdout — izlaz (deskriptor 1)
stdout je tok gde program šalje rezultate svog rada. Podrazumevano, stdout ide na ekran.
ls -l
Svaki red koji ls ispiše ide na stdout. Isti je slučaj sa echo, cat, date, whoami i praktično svakom komandom koja prikazuje rezultate.
echo "Zdravo svete" # "Zdravo svete" ide na stdout
date # datum i vreme idu na stdout
cat /etc/hostname # sadržaj fajla ide na stdout
stderr — greške (deskriptor 2)
stderr je tok za poruke o greškama i dijagnostička upozorenja. Podrazumevano, i stderr ide na ekran — ali odvojeno od stdout-a.
ls /nepostoji
ls: cannot access '/nepostoji': No such file or directory
Ova poruka greške ide na stderr, ne na stdout. Razlog za odvajanje: greške ne treba da se mešaju sa regularnim izlazom kada preusmeravaš stdout u fajl ili pajp.
Dijagram toka podataka
┌─────────────────────────────┐
Tastatura ───►│ stdin (fd 0) │
│ │
│ PROGRAM │───► stdout (fd 1) ───► Ekran
│ │
│ │───► stderr (fd 2) ───► Ekran
└─────────────────────────────┘
Svaki program koji se pokrene dobija ova tri toka automatski — bez obzira da li ih koristi ili ne.
Zašto je ovo važno?
Razumevanje standardnih tokova je preduslov za:
- Preusmeravanje — umesto da stdout ide na ekran, možeš ga preusmeriti u fajl (
>) - Pajpovi — stdout jedne komande postaje stdin sledeće (
|) - Upravljanje greškama — možeš odvojiti greške od normalnog izlaza (
2>) - Skriptovanje — skripte komuniciraju sa ostatkom sistema upravo kroz ove tokove
Komanda A ──► stdout ──┐
│ pajp (|)
▼
Komanda B ──► stdin ──► obradi ──► stdout ──► ...
Kada pišeš ls -l | grep ".txt", dešava se sledeće:
ls -lšalje sve na stdout- shell preusmeri taj stdout na stdin od
grep grepfiltrira linije i šalje rezultat na stdout- stdout od
grepide na ekran
Sve se svodi na tokove. Kada to jednom usvoji, preusmeravanje i pajpovi postaju intuitivni.