V Linuxu je text král a nejsilnější trik celého systému je zdánlivě banální: výstup jednoho programu pošleš jako vstup druhého. Místo jednoho obřího nástroje, který umí všechno, máš hromadu maličkých, z nichž každý dělá jednu věc dobře — a ty je skládáš dohromady jako díly na pásové lince. Tomuhle skládání se říká roura (
|) a je to srdce takzvané unixové filozofie. Až ti to „cvakne", přestaneš hledat speciální program na každý problém a začneš si nástroje řetězit.
Pár pojmů na úvod
- stdin (standardní vstup, kanál 0) = odkud program čte data. Klávesnice, soubor, nebo výstup předchozího příkazu v rouře.
- stdout (standardní výstup, kanál 1) = kam program píše svůj normální výsledek. Ve výchozím stavu terminál, ale dá se přesměrovat do souboru nebo do dalšího příkazu.
- stderr (chybový výstup, kanál 2) = kam program píše chyby a hlášky. Je zvlášť od stdout, aby ti chyby nezaneřádily užitečný výstup, když ho posíláš dál rourou.
- Přesměrování = přesměruješ proud jinam než na terminál — do souboru (
>,>>), ze souboru (<), nebo chyby stranou (2>). - Roura (pipe,
|) = spojka, která bere stdout levého příkazu a strká ho na stdin pravého. - Filtr = program, který čte ze stdin, něco s tím udělá a píše na stdout. Přesně ty se řetězí
do rour —
grep,sort,uniq,wc,cut,tr,sed,awk.
Tři proudy: vstup, výstup a chyby zvlášť
Každý program má od startu tři „trubky" napojené do světa. Představ si je jako tři barevné hadice:
- 0 — stdin: čtení dovnitř (co program dostává).
- 1 — stdout: normální výstup ven (co program „říká").
- 2 — stderr: chyby ven (co program „nadává").
Proč jsou výstup a chyby oddělené? Protože chceš umět poslat dál jen užitečná data, ale chybové
hlášky vidět na obrazovce. Kdyby byly smíchané, ls | grep neco by ti do výsledku občas propašovalo
i hlášku „soubor neexistuje" a rozbilo další zpracování.
# stdout jde do souboru, ale chyba se stejně vypíše na terminál
ls /existuje /neexistuje > vypis.txt
# → do vypis.txt se uloží nalezené, hláška o chybějícím souboru zůstane na obrazovce (stderr)
Přesměrování — kam tečou data
Přesměrování řekne shellu: „neposílej tenhle proud na terminál, ale sem".
echo "ahoj" > soubor.txt # stdout DO souboru — PŘEPÍŠE celý obsah!
echo "další" >> soubor.txt # stdout DO souboru — PŘIDÁ na konec (nepřepíše)
wc -l < soubor.txt # stdin ZE souboru (soubor krmí příkaz)
příkaz 2> chyby.log # stderr do souboru (chyby stranou)
příkaz &> vse.log # stdout I stderr do jednoho souboru
příkaz > vystup.log 2>&1 # totéž klasicky: "2 pošli tam, kam jde 1"
příkaz 2> /dev/null # chyby zahoď úplně (/dev/null = černá díra)
⚠️
>je nemilosrdné. Neptá se, nezálohuje — okamžitě vymaže obsah cílového souboru a napíše nový.>>naopak jen přidává. Nauč se ten rozdíl dřív, než si>omylem přepíšeš důležitý soubor.
Zápis 2>&1 čti jako „nasměruj kanál 2 tam, kam už míří kanál 1". Proto záleží na pořadí:
> soubor 2>&1 funguje (nejdřív 1 → soubor, pak 2 → za 1), kdežto 2>&1 > soubor pošle chyby ještě
na terminál, protože v tu chvíli 1 ještě míří na obrazovku.
Roura | — pásová linka z malých nástrojů
Roura je ta nejdůležitější věc v celé kapitole. Vezme stdout levého příkazu a napojí ho přímo na stdin pravého — bez ukládání do souboru, rovnou z paměti do paměti.
cat pristup.log | grep "ERROR" # vezmi log a nech jen řádky s ERROR
Tady je celá unixová filozofie: cat umí jen vypsat soubor, grep umí jen filtrovat řádky. Ani
jeden neumí to druhé — a to je záměr. Malé nástroje, každý dělá jednu věc dobře, a rourou z nich
poskládáš přesně to, co potřebuješ. Je to jako pásová linka: každý stroj udělá jeden úkon a pošle
polotovar dál.
Data tečou zleva doprava, každý díl je filtr — čte ze stdin, něco udělá, píše na stdout. Roura mezi nimi je ta trubka, co je propojuje.
Filtry, které použiješ pořád
Tohle je tvoje základní bedna nářadí. Každý z nich je filtr — dá se řetězit s ostatními.
grep — najdi řádky, které odpovídají vzoru.
grep "chyba" log.txt # řádky obsahující "chyba"
grep -i "chyba" log.txt # -i = ignoruj velikost písmen (Chyba, CHYBA…)
grep -n "chyba" log.txt # -n = přidej čísla řádků
grep -v "chyba" log.txt # -v = obrácení: řádky, které vzor NEobsahují
grep -r "TODO" . # -r = rekurzivně projdi celý strom adresářů
sort — seřaď řádky. uniq — zahoď opakující se sousední řádky.
sort jmena.txt # abecedně
sort -n cisla.txt # -n = číselně (jinak "10" < "2"!)
sort -rn cisla.txt # -r = obráceně (od největšího)
sort jmena.txt | uniq # unikátní řádky (uniq VYŽADUJE seřazený vstup!)
sort jmena.txt | uniq -c # -c = spočítej výskyty každého řádku
wc — počítání. cut — vyřízni sloupce. tr — nahraď/smaž znaky.
wc -l soubor.txt # -l = počet řádků (nejčastější použití)
cut -d':' -f1 /etc/passwd # -d = oddělovač, -f1 = první sloupec (uživatelská jména)
echo "Ahoj Svete" | tr 'a-z' 'A-Z' # převod na velká písmena → AHOJ SVETE
echo "a,b,c" | tr ',' '\n' # nahraď čárky novými řádky
sed a awk — ochutnávka dvou mocností
Až vyrosteš z grep/cut, čekají tě dva „těžkokalibrové" filtry. Teď jen ať víš, že existují.
sed — stream editor, hlavně na hledání a nahrazování textu:
sed 's/staré/nové/g' soubor.txt # nahraď "staré" za "nové" — g = na každém výskytu v řádku
cat log.txt | sed 's/ERROR/CHYBA/g' # v proudu přejmenuj ERROR na CHYBA
Čti s/co/čím/g jako substitute (nahraď) — co za čím, g = globálně (všechny výskyty na
řádku, ne jen první).
awk — nástroj na sloupce a tabulky. Umí toho hodně, ale nejčastěji ho uvidíš takhle:
awk '{print $1}' soubor.txt # vytiskni první sloupec každého řádku
awk '{print $1, $3}' soubor.txt # první a třetí sloupec
ps aux | awk '{print $2, $11}' # z výpisu procesů jen PID a název příkazu
$1, $2… jsou sloupce (rozdělené mezerami), $0 je celý řádek. Zatím ber sed a awk jako pozvánku
— až tě „malé filtry" přestanou stačit, vrátíš se k nim.
Praktická komba, co uvidíš každý den
Síla roury je v kombinaci. Pár klasik, které stojí za to umět nazpaměť:
# Kolik chyb je v logu?
cat aplikace.log | grep "ERROR" | wc -l
# Žebříček nejčastějších hodnot (top-fráze zdola nahoru)
cat pristup.log | cut -d' ' -f1 | sort | uniq -c | sort -rn
# Které IP adresy nás bušily nejvíc? (prvních 10)
cat pristup.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -10
To druhé kombo je klasika, kterou si zapamatuj: sort | uniq -c | sort -rn =
„spočítej výskyty a seřaď od nejčastějšího". Nejdřív sort (aby uniq viděl stejné řádky vedle sebe),
pak uniq -c (spočítá), pak sort -rn (seřadí číselně odshora). Přesně tak se dělá žebříček
četností — na cokoli od IP adres po slova v textu.
Failure modes — časté omyly začátečníků
>ti přepíše soubor bez varování.echo "x" > dulezity.txtvymaže starý obsah. Chceš-li přidat, je to>>. Když si nejsi jistý, nejdřív>>, přepsat můžeš vždycky.cmd < soubor > tentýž.soubor= katastrofa. Shell nejdřív vyprázdní cílový soubor kvůli>, teprve pak spustí příkaz — takže čteš z prázdna a přijdeš o data. Zapisuj do jiného souboru, pak přejmenuj.uniqbezsortnapřed.uniqzahazuje jen sousední duplicity. Bez předchozíhosortti nechá rozházené kopie a budeš se divit, proč tam pořád jsou. Pravidlo:uniqskoro vždy až posort.- Zapomenuté uvozovky u vzoru s mezerou.
grep chyba disku log.txtshell rozdělí —grephledáchybav souborechdiskualog.txt. Chcešgrep "chyba disku" log.txt. Vzor s mezerou vždy do uvozovek. - Chyby smíchané s daty. Když
příkaz | dalsinefunguje divně, může za to stderr. Přesměruj chyby (2> /dev/nullnebo2> chyby.log), ať vidíš jen čistý datový proud.
🛠️ Cvičení
- Přepiš vs. přidej. Vytvoř soubor přes
echo "první řádek" > pokus.txt, pak zkus jednou>a jednou>>s druhým textem a podívej se přescat pokus.txt, co se stalo. Vysvětli rozdíl vlastními slovy a řekni, kdy je>nebezpečné. - Postav rouru na počítání. Máš textový soubor s řádky. Napiš rouru, která spočítá, kolik řádků
obsahuje slovo
errorbez ohledu na velikost písmen. (Nápověda:grep -i,wc -l.) - Žebříček četností. Ze souboru, kde je na každém řádku jedno slovo (nebo z prvního sloupce logu),
vyrob top 5 nejčastějších hodnot i s počty. Poskládej
sort,uniq -c,sort -rn,head. - Sloupce a chyby stranou. Ze souboru
/etc/passwd(sloupce oddělené:) vytáhni jen uživatelská jména (první sloupec) a seřaď je abecedně. Zkus přitom nějaký příkaz, který částečně selže, a jeho chyby pošli do/dev/null. - stderr vs stdout. Spusť
ls existujici_slozka neexistujici_slozkaa rozděl výstup tak, aby normální výpis šel doout.txta chyby doerr.txt. Ověřcat, že v každém souboru je to správné.
Náčrt řešení — rozbal, až si cvičení zkusíš sám
- Přepiš vs. přidej —
echo "druhý" > pokus.txtsmaže „první řádek" a nechá tam jen „druhý".echo "druhý" >> pokus.txtnechá oba řádky.>je nebezpečné, protože maže okamžitě a bez ptaní — stačí omyl a přijdeš o obsah. Pozor:>vyprázdní soubor ještě před během příkazu, takžecmd < f > fzničíf. - Počítání řádků —
grep -i "error" soubor.txt | wc -l.grep -inajdeerror/Error/ERROR,wc -lspočítá řádky, které prošly. Pozor:wc -lpočítá řádky, ne výskyty — dvaerrorna jednom řádku se počítají jako jeden. Na výskyty by byl potřebagrep -onapřed. - Žebříček četností —
sort slova.txt | uniq -c | sort -rn | head -5. Nejdřívsort(aby stejná slova byla u sebe),uniq -cje spočítá,sort -rnseřadí číselně odshora,head -5vezme prvních pět. Pozor:uniqmusí jít až posort, jinak spočítá jen sousední duplicity a výsledek bude nesmysl. - Sloupce —
cut -d':' -f1 /etc/passwd | sort.-d':'říká, že oddělovač je dvojtečka,-f1bere první pole (jméno),sortseřadí. Chyby jiného příkazu utišíš přidáním2> /dev/null. Pozor:cutpočítá pole podle jednoho znaku oddělovače — víc mezer za sebou by dělalo prázdná pole (na to je lepšíawk). - stderr vs stdout —
ls existujici_slozka neexistujici_slozka > out.txt 2> err.txt.> out.txtchytí normální výpis (kanál 1),2> err.txtchytí chybu o chybějící složce (kanál 2). Pozor: pořadí2>&1je záludné —2>&1 > out.txtby chyby poslalo ještě na terminál, protože 1 v tu chvíli míří na obrazovku.
🧠 Otázky & odpovědi
K čemu je roura | a jak funguje?
Roura vezme stdout (normální výstup) levého příkazu a napojí ho přímo na stdin (vstup) pravého
příkazu — data tečou z paměti do paměti, bez ukládání do souboru. Díky tomu řetězíš malé nástroje
do delších pipeline: cat log | grep ERROR | wc -l = vypiš log, nech jen chybové řádky, spočítej je.
Je to jádro unixové filozofie „malé nástroje, každý dělá jednu věc dobře" — místo jednoho obřího
programu skládáš mnoho jednoúčelových jako díly na pásové lince.
Jaký je rozdíl mezi > a >>?
> přesměruje výstup do souboru a přitom ho přepíše — starý obsah okamžitě a bez varování zmizí.
>> výstup do souboru jen přidá na konec, původní obsah nechá být. Praktický důsledek: echo x > f
smaže f a nechá tam jen „x"; echo x >> f nechá, co bylo, a přidá řádek. Nejčastější začátečnická
katastrofa je omylem přepsat důležitý soubor přes >. Ještě zákeřnější je cmd < f > f — shell nejdřív
vyprázdní f a teprve pak čte, takže přijdeš o data.
Proč jsou stdout a stderr oddělené proudy?
Aby se ti chybové hlášky nemíchaly s užitečnými daty. Normální výstup jde na kanál 1 (stdout),
chyby na kanál 2 (stderr). Když posíláš výstup dál rourou (cmd | dalsi), teče tam jen stdout —
chyby zůstanou viditelné na terminálu a nerozbijí ti další zpracování. Můžeš s nimi nakládat zvlášť:
2> chyby.log chyby uložit, 2> /dev/null úplně zahodit, 2>&1 je spojit s výstupem. Kdyby byly
v jednom proudu, každá hláška „soubor nenalezen" by ti zaneřádila data.
Proč se uniq skoro vždy dává až po sort?
Protože uniq zahazuje jen sousední stejné řádky — nehledá duplicity po celém souboru, jen porovnává
každý řádek s tím předchozím. Když jsou stejné hodnoty rozházené po souboru, uniq je nechá být.
sort je proto srovná vedle sebe a teprve pak uniq funguje správně. Odtud pochází klasické kombo
sort | uniq -c | sort -rn na žebříček četností: seřaď, spočítej výskyty (-c), a znovu seřaď
číselně odshora podle počtu.
K čemu jsou grep, cut, sort, wc a kdy který?
Jsou to základní filtry — čtou ze stdin, něco udělají, píšou na stdout. grep hledá řádky podle
vzoru (-i ignoruj velikost, -v obrať, -r rekurzivně, -n čísla řádků). cut vyřízne sloupce
(-d oddělovač, -f číslo pole) — na text s pevnými sloupci jako /etc/passwd. sort seřadí (-n
číselně, -r obráceně). wc -l spočítá řádky. Poskládané rourou pokryjí většinu každodenní práce
s textem; na složitější úpravy pak přijdou sed (nahrazování) a awk (sloupce a tabulky).
