Proces je běžící instance programu — program je jen soubor na disku (třeba
/usr/bin/firefox), proces je ten samý program naživu v paměti, s vlastním číslem, právy a otevřenými soubory. Jeden program můžeš spustit desetkrát a máš deset procesů. Když se naučíš procesy vidět, řadit do popředí a pozadí a posílat jim signály, přestaneš být bezmocný ve chvíli, kdy něco „zamrzne" nebo drží port — a nebudeš první ranou stříletkill -9.
Pár pojmů na úvod
- Proces = běžící instance programu (program v paměti, ne soubor na disku).
- PID (Process ID) = jedinečné číslo procesu. Podle něj ho oslovuješ (
kill 1234). - PPID (Parent PID) = číslo rodiče — procesu, který tenhle proces spustil. Každý proces má rodiče.
- PID 1 = úplně první proces, který jádro nastartuje. Dnes je to skoro vždy systemd (dřív „init"). Je to praotec všech ostatních procesů a nikdy neumírá, dokud běží systém.
- Signál = malá zpráva poslaná procesu („skonči", „pozastav se", „znovu načti config"). Způsob, jak s procesy mluvíš zvenčí.
- Job (úloha) = proces spuštěný z tvého shellu, který shell sleduje (kvůli
fg/bg/jobs).
Co je proces a jak vzniká strom
Když spustíš program, jádro vytvoří proces: přidělí mu PID, kus paměti a zapamatuje si, kdo ho
spustil (PPID). A tady je klíč: v Linuxu každý proces vzniká z jiného procesu. Tvůj shell (bash)
spustí firefox → firefox je dítě shellu, shell je jeho rodič. Shell zase spustil terminál,
terminál spustil systemd… až úplně nahoře je PID 1 (systemd), praotec všeho.
Vznikne tak strom procesů — jeden kořen, z něj větve. Podívat se na něj můžeš takhle:
pstree -p # strom procesů s PID v závorkách
ps -ef --forest # totéž ve sloupcích, odsazené podle rodičů
💡 Proč to tak je? Když nějaký proces spadne, jádro to oznámí jeho rodiči (ten „sebere výsledek"). A když rodič zemře dřív než dítě, dítě nezůstane bez dozoru — adoptuje ho PID 1. Strom drží pořádek v tom, kdo za koho odpovídá.
Jak si procesy prohlédnout
ps — snímek v jednu chvíli
ps vypíše procesy tak, jak vypadají teď (statický snímek, ne živě). Dvě nejčastější kouzelné
formule, které si prostě zapamatuj:
ps aux # všechny procesy všech uživatelů, „user-friendly" sloupce
ps -ef # totéž, jiný (klasický Unix) formát — často s PPID
Nenech se zmást tím, že aux je bez pomlčky a -ef s pomlčkou — jsou to dva historické styly ps,
které dělají skoro totéž. Sloupce u ps aux, které tě zajímají:
| Sloupec | Co znamená |
|---|---|
PID | číslo procesu |
%CPU | kolik procesoru zrovna žere |
%MEM | kolik paměti žere |
STAT | stav procesu (viz níže) |
COMMAND | čím byl spuštěn |
STAT ti řekne, co proces dělá: R = běží/připraven, S = spí (čeká na něco, úplně normální),
D = nepřerušitelný spánek (typicky čeká na disk), T = zastavený (uspaný přes Ctrl+Z), Z =
zombie (o tom níž). Písmena se kombinují se symboly (S+ = spí a je v popředí).
top / htop — živě a interaktivně
ps je fotka, top je video. Ukazuje procesy živě, řazené podle vytížení, a čísla se aktualizují.
top # skoro všude, ovládá se klávesami (q = konec)
htop # hezčí, barevné, myš, F-klávesy — nutno doinstalovat
V htop vidíš zátěž jader nahoře, seznam procesů dole, a přímo v něm můžeš proces zabít (F9) nebo
změnit prioritu (F7/F8). Pro rychlé „co mi žere procesor" je htop nejlepší kamarád.
pgrep — najdi PID podle jména
Když chceš jen zjistit PID něčeho konkrétního, nemusíš očima prohledávat ps aux:
pgrep firefox # vypíše PID(y) všech procesů „firefox"
pgrep -a sshd # -a přidá i celý příkaz, ať víš, že jsi trefil to pravé
Popředí, pozadí a úlohy
Když spustíš příkaz normálně, běží v popředí — drží ti terminál a ty čekáš, než doběhne. Často to ale nechceš (dlouhý build, server, kopírování). Řešení je pustit ho do pozadí.
sleep 300 & # & na konci = spusť rovnou na pozadí, terminál máš hned volný
A když už příkaz běží v popředí a až teď si to rozmyslíš?
# 1) stiskni Ctrl+Z → proces se USPÍ (zastaví) a vrátí ti prompt
# 2) rozjeď ho na pozadí:
bg # „background" — pokračuj, ale na pozadí
# nebo ho vrať zpět do popředí:
fg # „foreground" — zase drží terminál
Přehled toho, co ti v shellu běží, dá jobs:
jobs # seznam úloh tohoto shellu s čísly [1], [2]…
fg %2 # vrať do popředí úlohu číslo 2
kill %1 # zabij úlohu číslo 1 (přes číslo úlohy, ne PID)
⚠️ Pozor na rozdíl Ctrl+Z vs Ctrl+C.
Ctrl+Cproces ukončí (pošle SIGINT).Ctrl+Zho jen uspí (pošle SIGTSTP) — pořád existuje, jen stojí. Když na uspaný proces zapomeneš a zavřeš terminál, může viset dál.
Ať to přežije zavření terminálu
Normálně platí: zavřeš terminál → jeho procesy dostanou SIGHUP a umřou. To u dlouhých úloh na serveru nechceš. Dvě cesty:
nohup ./dlouhy-skript.sh & # „no hangup" — ignoruje SIGHUP, výstup jde do nohup.out
./dlouhy-skript.sh & # spustíš na pozadí
disown # odpojíš úlohu od shellu → SIGHUP ji nezasáhne
💡 Pro serióznější „ať to běží i po odhlášení" se používají
tmuxneboscreen(celé sezení, do kterého se dá vrátit). Ale na jeden příkaznohup/disownbohatě stačí.
Signály — jak s procesy mluvíš
Signál je krátká zpráva, kterou jádro doručí procesu. Neposíláš text — posíláš číslo/jméno a proces na něj (většinou) nějak reaguje. Ty nejdůležitější:
| Signál | Číslo | Co říká | Dá se odchytit? |
|---|---|---|---|
SIGTERM | 15 | „slušně skonči, ukliď po sobě" (výchozí u kill) | ano |
SIGKILL | 9 | „umři teď, hned, bez řečí" | NE |
SIGINT | 2 | „přeruš se" — to posílá Ctrl+C | ano |
SIGHUP | 1 | „zavřel se terminál" / u démonů často „znovu načti config" | ano |
SIGTSTP | 20 | „uspi se" — to posílá Ctrl+Z (jde odchytit) | ano |
SIGSTOP | 19 | vynucený stop (ručně kill -STOP) | NE |
SIGCONT | 18 | „pokračuj" (probudí zastavený proces) | ano |
Klíčový rozdíl: SIGTERM vs SIGKILL. SIGTERM je zdvořilá žádost — proces ji může odchytit, uložit rozdělanou práci, zavřít soubory, uvolnit zámky a pak skončit. SIGKILL nejde odchytit ani odmítnout; jádro proces zabije v tu ránu. To je mocné, ale proto i nebezpečné (viz Failure modes).
Nástroje na posílání signálů
kill 1234 # pošle SIGTERM (15) procesu s PID 1234 — slušné ukončení
kill -9 1234 # pošle SIGKILL (9) — tvrdé zabití (až když TERM nezabral)
kill -HUP 1234 # pošle SIGHUP — třeba „přenačti config" u serveru
killall firefox # zabij VŠECHNY procesy jménem „firefox“
pkill -f skript.sh # zabij procesy, jejichž příkazová řádka odpovídá vzoru
kill mluví přes PID, killall přes přesné jméno, pkill přes vzor (regulární výraz nad jménem/
příkazem). pkill -f hledá i v celé příkazové řádce — užitečné, ale snadno tím trefíš víc, než chceš.
Proč NEsahat rovnou po kill -9
Nejčastější začátečnický reflex je „nefunguje to → kill -9". Nedělej to jako první. SIGKILL
proces zabije uprostřed čehokoli dělá:
- rozepsaná data se neuloží (databáze, editor),
- zámky a dočasné soubory zůstanou (proces se nedostal k úklidu → příště „už to běží / soubor zamčen", i když nic neběží),
- u databází může zůstat poškozený stav.
Správný postup je odstupňovaný: nejdřív kill (SIGTERM), dej procesu pár vteřin, ať se v klidu
vypne, a teprve když nereaguje, přitvrď na kill -9. SIGKILL je poslední pojistka, ne první volba.
Zombie a orphan — dva strašáci (a proč se jich nebát)
Znějí děsivě, ale jsou to jen dva normální stavy ve stromu procesů:
- Zombie (
Zve STAT) = proces, který doběhl, ale jeho rodič si ještě nesebral výsledek (návratový kód). Zombie už nic nedělá a nežere paměť — je to jen řádek v tabulce, „vzkaz čeká na vyzvednutí". Zmizí, jakmile ho rodič sebere (wait). Zabít zombii nejde (už je „mrtvá") — když jich je moc, problém je rodič, který si výsledky nesbírá; řešíš tedy rodiče (restart / kill rodiče). - Orphan (sirotek) = proces, jehož rodič umřel dřív než on. Takový proces nezůstane bez dozoru: automaticky ho adoptuje PID 1 (systemd), který za něj pak převezme roli rodiče (a sebere po něm výsledek). Sirotci jsou úplně v pořádku a běžní.
💡 Pointa: hromada zombie = signál, že nějaký program má bug v úklidu po dětech, ne že „musíš honit zombie". Restartuj (nebo zabij) jejich rodiče a zombie zmizí s ním.
Priorita procesů — nice a renice (krátce)
Když víc procesů chce procesor, jádro je řadí podle priority. Tu ovlivníš hodnotou nice: rozsah −20 (nejvyšší priorita, „nejsem hodný, chci CPU") až +19 (nejnižší, „jsem hodný, ostatní mají přednost"). Běžný uživatel smí prioritu jen snižovat (zvyšovat = jen root).
nice -n 10 ./narocny-vypocet.sh # spusť rovnou s nižší prioritou (hodnota +10)
renice -n 5 -p 1234 # změň prioritu už běžícího procesu (PID 1234)
Typické použití: pustíš dlouhý build nebo kompresi s nice, ať ti neseká zbytek systému.
Failure modes — časté omyly začátečníků
kill -9jako první volba. Zabiješ proces bez úklidu → ztráta rozdělaných dat, viselé zámky. Vždycky nejdřívkill(SIGTERM), pauza, a-9až když nereaguje.- Zabití špatného PID. Zkopíruješ číslo z rychlíku a odstřelíš nevinný (nebo důležitý systémový)
proces. Než pošleš signál, ověř si, co PID je:
ps -p 1234 -o pid,cmdnebopgrep -a. - Proces zůstal v pozadí a drží port. Server jsi „ukončil" přes Ctrl+Z (jen uspal!) nebo přes
&a zapomněl na něj → „port už je obsazený". Najdi viníka:ss -tlnp | grep :3000(nebolsof -i :3000) a teprve pak ho cíleně ukonči. - Honění zombie. Snažíš se zombii zabít přímo — nejde to, je už mrtvá. Řeš rodiče, ne zombii.
pkill -fodstřelí víc, než chceš. Vzor sedí i na jiné procesy (třeba na tvůjgrepnebo editor s tím jménem v cestě). Nejdřívpgrep -af vzora zkontroluj seznam, pak teprvepkill.
🛠️ Cvičení
- Najdi rodiče. Spusť
sleep 500 &, pak zjisti jeho PID a PPID. Kdo je jeho rodič? Ověř, že PPID odpovídá tvému shellu. (Nápověda:pgrep,ps -o pid,ppid,cmd -p <PID>.) - Popředí ↔ pozadí. Spusť
sleep 300v popředí, uspi ho přes Ctrl+Z, mrkni najobs, pošli ho na pozadí přesbga pak zase zpět do popředí přesfg. Popiš, co se v každém kroku stalo. - Slušně vs tvrdě. Spusť si nějaký vlastní
sleep 999 &. Ukonči ho nejdřív obyčejnýmkill <PID>(SIGTERM). Pak druhý spusť znovu a zkuskill -9 <PID>. Jaký je rozdíl a kdy který použít? - Kdo drží port. Najdi příkaz, kterým zjistíš, jaký proces poslouchá na konkrétním TCP portu
(třeba 22). (Nápověda:
ss -tlnp.) Proč je lepší vědět PID, než stříletkillallnaslepo? - Priorita. Spusť
nice -n 15 sleep 200 &a vps/htopsi najdi jeho nice hodnotu (NI). Proč bys náročný výpočet pustil s vyšší nice hodnotou?
Náčrt řešení — rozbal, až si cvičení zkusíš sám
- Najdi rodiče —
PID=$(pgrep -n sleep)chytne PID naposledy spuštěnéhosleep, pakps -o pid,ppid,cmd -p $PIDukáže PID i PPID. PPID se rovná PID tvého shellu (ověřecho $$— to je PID aktuálního bashe). Rodičem je shell, protože on tensleepspustil. Pozor:&proces neodpojí od rodiče, jen ho pustí na pozadí — rodičem zůstává shell (odpojí ho aždisown/ smrt shellu → adopce PID 1). - Popředí ↔ pozadí — v popředí
sleepdrží terminál (nemáš prompt). Ctrl+Z pošle SIGTSTP → proces se zastaví (STATT) a vrátí se prompt;jobsho ukáže jakoStopped.bgpošle SIGCONT a nechá ho běžet na pozadí (Running), terminál máš volný.fgho vytáhne zpět do popředí. Pozor: Ctrl+Z neukončuje, jen uspává — zapomenutý uspaný job pořád existuje. - Slušně vs tvrdě —
kill <PID>pošle SIGTERM (15): proces dostane šanci se v klidu vypnout (uložit, uklidit).kill -9 <PID>pošle SIGKILL: jádro ho zabije okamžitě, bez možnosti úklidu. Usleepje výsledek stejný (nemá co ukládat), ale u reálného programu (databáze, editor) může-9znamenat ztrátu dat a viselé zámky. Pozor:-9je poslední možnost, ne první — nejdřív vždy SIGTERM a chvíli počkej. - Kdo drží port —
ss -tlnp(nebosudo ss -tlnp sport = :22) vypíše naslouchající TCP porty i s PID/jménem procesu; alternativalsof -i :22. Bez sudo někdy neuvidíš cizí PID. Znát konkrétní PID je lepší, protožekillall <jméno>odstřelí všechny procesy toho jména (i ty, co s portem nesouvisí) — cílenýkill <PID>zasáhne jen viníka. Pozor: nezaměň naslouchající proces (LISTEN) za pouhé připojení. - Priorita —
NIsloupec vps -o pid,ni,cmd/htopukáže nice15. Vyšší nice = „hodnější" proces = nižší priorita → jádro dá přednost ostatním, takže náročný výpočet ti neseká interaktivní práci (myš, terminál). Pozor: běžný uživatel smí nice jen zvyšovat (snižovat prioritu); zpět dolů (−) smí jen root.
🧠 Otázky & odpovědi
Jaký je rozdíl mezi programem a procesem?
Program je nehybný soubor na disku (např. /usr/bin/firefox) — recept. Proces je ten program
spuštěný a živý v paměti: má vlastní PID, přidělenou paměť, práva a otevřené soubory. Z jednoho
programu můžeš mít víc procesů současně (deset otevřených terminálů = deset procesů z jednoho
binárního souboru). Jakmile proces doběhne nebo ho ukončíš, zmizí z paměti — program na disku zůstává.
Co je PID 1 a proč je důležitý?
PID 1 je úplně první proces, který jádro nastartuje při bootu — dnes skoro vždy systemd (dřív „init"). Je to praotec všech ostatních procesů: přímo nebo přes potomky z něj vzejde všechno ostatní. Má dvě zvláštní role: spouští a hlídá systémové služby (démony) a adoptuje sirotky — procesy, jimž umřel rodič, aby nezůstaly bez dozoru a někdo po nich sebral výsledek. PID 1 běží, dokud běží systém; když spadne, padá celý stroj.
Kdy použít SIGTERM a kdy SIGKILL?
Vždycky nejdřív SIGTERM (kill <PID>, signál 15). Je to zdvořilá žádost „skonči" — proces ji může
odchytit, uložit rozdělanou práci, zavřít soubory a uvolnit zámky, a pak v klidu skončit. Teprve když
nereaguje (visí, ignoruje TERM), sáhni po SIGKILL (kill -9, signál 9) — ten nejde odchytit
ani odmítnout, jádro proces zabije okamžitě. Cena za to je, že se proces nestihne uklidit: hrozí
ztráta dat a viselé zámky. Proto je -9 poslední pojistka, ne první reflex.
Co je zombie proces a jak se ho zbavit?
Zombie (Z ve STAT) je proces, který už doběhl, ale jeho rodič si ještě nesebral výsledek
(návratový kód). Zombie nic nedělá a nežere paměť — je to jen záznam v tabulce, „vzkaz čeká na
vyzvednutí". Zabít ji nejde (už je mrtvá) — SIGKILL na ni nezabere. Zmizí sama, jakmile si ji rodič
vyzvedne. Když se hromadí, viník je rodičovský proces, který si výsledky po dětech nesbírá (bug) —
řešíš tedy jeho: restartuješ ho, nebo ho ukončíš (pak zombie zdědí a uklidí PID 1).
Proč mi proces po zavření terminálu umřel a jak tomu zabránit?
Protože zavřením terminálu jádro pošle jeho procesům SIGHUP („hang up") — a výchozí reakce na
SIGHUP je skončit. U dlouhých úloh to nechceš. Řešení: spusť příkaz přes nohup ./skript & (ignoruje
SIGHUP, výstup jde do nohup.out), nebo ho pusť na pozadí a hned disown (odpojí úlohu od shellu,
takže ji SIGHUP nezasáhne). Pro delší práci na serveru je nejlepší tmux nebo screen — celé
sezení, do kterého se po opětovném přihlášení vrátíš přesně tam, kde jsi skončil.
