Gym
lesson

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:

  1. Preusmeravanje — umesto da stdout ide na ekran, možeš ga preusmeriti u fajl (>)
  2. Pajpovi — stdout jedne komande postaje stdin sledeće (|)
  3. Upravljanje greškama — možeš odvojiti greške od normalnog izlaza (2>)
  4. 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
  • grep filtrira linije i šalje rezultat na stdout
  • stdout od grep ide na ekran

Sve se svodi na tokove. Kada to jednom usvoji, preusmeravanje i pajpovi postaju intuitivni.