Linux: Kniha kouzel, vanilková příchuť 1.17 (27. února 2022)
Veškerá moc příkazové řádky/příkazového řádku přehledně, pro začátečníky i pokročilé

18. Správa procesů

Řada 1.x vanilkové příchuti Linuxu: Knihy kouzel je od 1. října 2020 do 1. března 2023 ve stavu dlouhodobé pasivní údržby; nahlášené chyby budou opravovány, ale aktivní vývoj se již věnuje novější vývojové řadě určené pro novější verze operačního systému a programů. Pokud nejste vázáni na starší verze programů, doporučuji vyhledat novou verzi z aktivně vyvíjené vývojové řady.
bash procesy systém tematický okruh

1. Úvod

Tato kapitola pokrývá vyhledávání, zkoumání, sledování a ukončování procesů a omezeně také jejich spouštění. Rovněž se zabývá sledováním, jak jednotlivé procesy využívají systémové zdroje jako výkon procesoru, paměť RAM či pevný disk. Ne všechny uvedené postupy však fungují pro zacházení s démony; hodláte-li zacházet s démony, navštivte kapitolu Systém.

Když v Linuxu spustíte program, vznikne tzv. proces – jakási „schránka“ pro program, která mu umožňuje běžet na procesoru a využívat systémové zdroje. Většina příkazů, které v terminálu zadáte, vytvoří nový proces. Pouze malá část spuštěných procesů si otevře také grafické uživatelské rozhraní.

Procesy jsou v Linuxu identifikovány čísly PID (což neznamená „Pražská integrovaná doprava“) a jsou uspořádány do „rodinné“ struktury, kde každý proces s výjimkou dvou prvotních démonů má právě jednoho rodiče. PID rodiče je u vlastního procesu uvedeno jako vlastnost „PPID“. (Pozor – nepleťte si PID a PPID!)

Tato verze kapitoly nepokrývá sledování systémových volání procesů (ptrace, strace) ani zjišťování, které systémové knihovny jsou procesy využívány.

Tato kapitola se nezabývá správou systémových zdrojů z celkového hlediska, ani používáním kvót, kontejnerů či izolačních a virtualizačních technik jako chroot či cgroups.

2. Definice

3. Zaklínadla

3/1 Hledání procesů (najít PID)

procesy podle názvu procesu (obecně/příklad)#1
pgrep [-x] 'regulární výraz'
pgrep '^gimp'
všechny procesy#2
pgrep .
přímí/všichni potomci určitého procesu#3
pgrep -P PID
lkk procesy | sed -E 's/^([0-9]+)(:[0-9]+)*:(PID):.*/\1/;t;d'
proces a všichni jeho předci v pořadí, až po prvotního démona#4
lkk procesy | sed -nE '/^(PID):/{s/:/\n/g;p}'
procesy, které mají otevřený konkrétní soubor#5
sudo fuser cesta 2>/dev/null | sed -E 's/^\s+//;s/\s+|\s?$/\n/g'
všechny procesy určitého uživatele/určité skupiny#6
pgrep -U uid-nebo-uživatel[,další]
pgrep -G gid-nebo-skupina[,další]
sourozenci určitého procesu (včetně procesu samotného)#7
pgrep -P $(ps h -o ppid PID-procesu)
procesy spuštěné později či společně se zadaným procesem#8
ps h -eo etimes,pid --sort -etimes | gawk '$1 <= '"$(ps h -o etimes:1 PID)"' {print $2}'
procesy spuštěné dříve či společně se zadaným procesem#9
ps h -eo etimes,pid --sort -etimes | gawk '$1 >= '"$(ps h -o etimes:1 PID)"' {print $2}'
procesy, které mají otevřený konkrétní adresář#10
sudo fuser cesta 2>/dev/null | sed -E 's/^\s+//;s/\s+|\s?$/\n/g'

3/2 Zjistit obecné informace o procesu

příkazový řádek (pro člověka/txtz pro skript)#1
tr \\0 \\40 </proc/PID/cmdline | sed -E '$s/ ?$/\n/' | cat -v
cat /proc/PID/cmdline [| zpracování]
ARGV[0]#2
head -zn1 /proc/PID/cmdline | tr \\0 \\n⊨ /bin/bash
PPID#3 (1)
ps h -o ppid:1 -p PID⊨ 3077
název procesu#4
ps h -o comm:1 -p PID⊨ bash
spuštěný soubor (na disku)#5
[sudo] readlink /proc/PID/exe⊨ /bin/bash
příslušný terminál#6 (2)
ps h -o tty:1 -p PID⊨ pts/1
aktuální adresář (pro člověka/pro skript)#7
[sudo] pwdx PID⊨ 2343: /home/nana
[sudo] readlink /proc/PID/cwd⊨ /home/nana
uživatel vlastnící proces (jméno/UID)#8
ps h -o ruser:1 -p PID⊨ root
ps h -o ruid:1 -p PID⊨ 0
skupina vlastnící proces (jméno/GID)#9
ps h -o rgroup:1 -p PID⊨ root
ps h -o rgid:1 -p PID⊨ 0
priorita procesu#10
ps h -o ni:1 -p PID⊨ 0
označení sezení podle systemd#11
ps h -o lsession:1 -p PID⊨ c2

3/3 Zjistit okamžité využití zdrojů

% zatížení procesoru#1
ps h -o pcpu:1 -p PID⊨ 10.1
počet kiB RAM zabrané procesem#2
ps h -o rss:1 -p PID⊨ 6028
% RAM zabrané procesem#3
ps h -o pmem:1 -p PID⊨ 0.1
velikost virtuální paměti procesu v kiB#4
ps h -o vsz:1 -p PID⊨ 32024
počet kiB virtuální paměti zabrané kódem/daty#5
ps h -o trs:1 -p PID⊨ 1037
ps h -o drs:1 -p PID⊨ 30986
procesy, které nejvíc zatěžují procesor/RAM#6
ps h -e -o pcpu,pid,comm | sort -rn | head
ps h -e -o rss,pid,comm | sort -rn | head
číslo přiděleného logického procesoru (od nuly)#7
ps h -o psr:1 -p PID⊨ 0
počet vláken #8
sed -E 's/^Threads:\s+//;t;d' /proc/PID/status⊨ 1
procesy, které nejvíc pracují s diskem#9
sudo egrep -H '^(read|write)_bytes:' /proc/[1-9]*/io >dočasný/soubor/1
sleep 1;sudo egrep -H '^(read|write)_bytes:' /proc/[1-9]*/io >dočasný/soubor/2
gawk 'BEGIN {FS="/|: ?"; OFS = "\t";} ARGIND == 1 {A[$3] += $6} ARGIND == 2 {B[$3] += $6} END {for (pid in A) {if (pid in B) {print B[pid] - A[pid], pid}}}' dočasný/soubor/1 dočasný/soubor/2 | sort -rn | head

3/4 Zjistit historii využití zdrojů

čas od spuštění procesu (v sekundách/ve formátu [[DD-]hh:]mm:ss)#1
ps h -o etimes:1 -p PID⊨ 271
ps h -o etime:1 -p PID⊨ 04:31
ɵčas, od kdy proces existuje#2
ps h -o lstart -p PID | date -f - "+%F %T %z"⊨ 2020-02-07 13:42:13 +0100
spotřebovaný čas procesoru#3
ps h -o cputime:1 -p PID⊨ 00:01:13
počet bajtů přečtených z disku/zapsaných na disk#4
[sudo] sed -E 's/^read_bytes:\s+//;t;d' /proc/PID/io⊨ 1503232
[sudo] sed -E 's/^write_bytes:\s+//;t;d' /proc/PID/io⊨ 1724416

3/5 Zjistit ostatní údaje

seznam otevřených deskriptorů (jen čísla/s cestami k souborům)#1
[sudo] ls -U1 /proc/PID/fd
[sudo] find /proc/PID/fd -type l -printf '%f\t%l\n'
vypsat prostředí procesu ve formátu txtz#2 (3)
[sudo] cat /proc/PID/environ [| zpracování]
efektivní uživatel (jméno/EUID)#3
ps h -o euser:1 -p PID⊨ root
ps h -o euid:1 -p PID⊨ 0
efektivní skupina (jméno/EGID)#4
ps h -o egroup:1 -p PID⊨ root
ps h -o egid:1 -p PID⊨ 0

4. Zaklínadla (TUI a stromové zobrazení)

4/1 Stromové zobrazení

proces a jeho potomci#1
pstree -pT[h][l] PID
proces a jeho předkové#2
pstree -ps[h][l] PID
všechny procesy bez parametrů/s parametry#3
pstree -pT[h][l]
pstree -paT[h][l]

4/2 TUI

procesy nejvíc zatěžující CPU#1
top
procesy zabírající nejvíc paměti RAM#2
top
Shift + M
procesy nejvíc vytěžující pevný disk#3
sudo iotop
procesy spotřebovávající nejvíc elektřiny#4 (4)
sudo powertop

5. Zaklínadla (spouštění a ovládání procesů)

5/1 Spouštění procesů

spustit příkaz s právy superuživatele/jiného uživatele#1
sudo příkaz [parametr-příkazu]
sudo -u uživatel příkaz parametr-příkazu
spustit příkaz s právy jiné skupiny#2
sg "příkaz [parametr-příkazu]"
spustit příkaz a po skončení vypsat spotřebovaný čas#3 (5)
time příkaz [parametr-příkazu]
spustit příkaz a jeho programem nahradit volající bash či sh#4
exec příkaz [parametr-příkazu]
spustit proces s nastavenou prioritou (ne vyšší/libovolnou)#5
nice -n $((priorita - $(nice))) příkaz [parametry příkazu]
sudo nice -n $((priorita - $(nice))) sudo -u "$(id -nu)" -g "$(id -ng)" příkaz [parametry příkazu]

5/2 Ukončování procesů

požádat o ukončení více procesů podle názvu (obecně/příklad)#1
[sudo] pkill 'regulární-výraz'
pkill '^gimp'
požádat o ukončení/násilně ukončit#2
[sudo] kill PID
[sudo] kill -9 PID

5/3 Čekání, signály, priorita

počkat na ukončení#1
while test -e /proc/PID; do IFS="" read -t 0.1 || :; done <> <(:)
zaslat procesu signál#2
[sudo] kill -[signál] PID
pozastavit proces/nechat ho pokračovat#3
[sudo] kill -SIGSTOP PID
[sudo] kill -SIGCONT PID
změnit prioritu běžícího procesu#4 (6)
[sudo] renice priorita PID

5/4 Úlohy bashe

spustit příkaz na pozadí#1
příkaz [parametr-příkazu] &
požádat proces v popředí o ukončení#2
Ctrl + C
pozastavit proces v popředí a odsunout ho jako úlohu bashe#3
Ctrl + Z
přenést úlohu na popředí#4 (7)
fg [%číslo-úlohy]
vypsat seznam úloh#5
jobs
nechat pozastavenou úlohu pokračovat v pozadí#6
bg [%číslo-úlohy]
požádat úlohu o ukončení/násilně ji ukončit#7
kill %číslo-úlohy
počkat na dokončení úlohy běžící v pozadí#8
wait %číslo-úlohy [%číslo-další-úlohy]

6. Parametry příkazů

6/1 ps

ps parametry [-e]
ps parametry PID
☐ --no-headersPotlačí zobrazení hlavičky na začátku výpisu.
☐ -o sloupceUrčí, které sloupce se vypíšou. Seznam platných hodnot najdete v manuálové stránce příkazu ps.
○ -eZobrazit všechny procesy v systému. (Výchozí chování: zobrazí jen procesy příslušné témuž terminálu.)
☐ -HOdsadí názvy příkazů pro zdůraznění struktury stromu procesů.
☐ --sort klíčeNastaví řazení výpisu.

6/2 pgrep

pgrep [volby] 'regulární výraz'
pgrep [volby a kritéria] ['regulární výraz']

Volby:

☐ -xU regulárního výrazu požadovat přesnou shodu.
○ -o ○ -n ○ -vZ nalezených procesů vybrat: jen nejstarší proces/jen nejnovější proces/všechny procesy, které nevyhovují kritériím. (Výchozí: všechny procesy vyhovující kritériím.) Poznámka: staří procesu se zde posuzuje podle času spuštění.
☐ -fRegulární výraz testovat proti celé příkazové řádce procesu. (Normálně jen proti názvu procesu.)
☐ -d řetězecNastavit oddělovač výpisu nalezených PID.
○ -c ○ -l ○ -aVypsat: jen počet nalezených PID; PID a název procesu; PID a příkazový řádek procesu.
☐ -iPři testu regulárního výrazu nerozlišovat velká a malá písmena.

Kritéria:

☐ -G gid-nebo-skupina...Vybrat podle skupiny (RGID).
☐ -P PPID...Vybrat podle PPID.
☐ -t terminál...Vybrat podle příslušného terminálu (např. „pts/1“).
☐ -u uid-nebo-uživatel...Vybrat podle EUID.
☐ -U uid-nebo-uživatel...Vybrat podle RUID.

7. Instalace na Ubuntu

Většina uvedených příkazů je základními součástmi Ubuntu. Pouze některé konkrétní příkazy ve stejnojmenných balíčcích je potřeba doinstalovat, pokud je chcete použít:

sudo apt-get install iotop powertop

V kapitole je použit také příkaz gawk:

sudo apt-get install gawk

8. Tipy a zkušenosti

9. Další zdroje informací

10. Pomocné skripty

lkk procesy – vypíše přehled procesů ve snadno zpracovatelném tvaru#1
#!/usr/bin/gawk -bf
BEGIN {
while ("ps h -e -o pid,ppid" | getline) {ppids[pids[++n] = $1] = $2}
OFS = ORS = "";
for (i = 1; i <= n; ++i) {
print pid = pids[i];
while ((pid = ppids[pid]) in ppids) {print ":", pid}
print "\n";
}
}
1 Pro procesy zřízené jádrem (systemd a kthreadd) vrací „0“.
2 Nepříluší-li proces žádnému terminálu ani konzoli, vypíše „?“.
3 Každý záznam začíná názvem proměnné prostředí a znakem „=“, za ním následuje obsah proměnné.
4 Funguje především na notebooku, nemám příliš vyzkoušené.
5 Jde o vestavěnou konstrukci bashe, která dovoluje na místo jednoduchého příkazu zadat také více příkazů spojených rourou, např. „time seq 10000 | wc -l“. Účinek příkazu „time“ se pak vztahuje na všechny procesy spojené rourou.
6 Priorita je číslo v rozsahu -20 (nejvyšší) až 19 (nejnižší); normální priorita je 0. Obyčejný uživatel (tzn. bez sudo) může pouze snižovat prioritu vlastních procesů.
7 Byla-li úloha pozastavená, tento příkaz ji nechá pokračovat.
Regulární výrazyAWKBarvy, titulek a výzva terminálu