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.
