Dla administratora w jego codziennej działalności najporęczniejszą komendą do obserwacji
procesów w systemie jest top|htop. Do uzyskania obrazu całego drzewa genealogicznego
procesów wygodnie jest użyć komendy pstree -[ch].
Podstawową komendą do szczegółowej analizy działania procesów w systemie jest ps
(zob. man ps). Korzystając z tej komendy można używać opcji podawanych w stylu UNIX,
BSD oraz GNU.
Obserwacja procesów związanych z daną sesją:
# ps
# ps -w
# ps -f|F
# ps -f -t tty1
# ps -fw
# ps -l
# ps -lf
# ps -L[f]
# ps -Fl
Obserwacja procesów w systemie:
# ps -e
# ps -ew
# ps -e[fF]
# ps -ef -t pts/14
# ps -ef -t tty1
# ps -ejH
# ps -U user
Przykłady opcji w stylu BSD wg stron podręcznika:
# ps ax
# ps axu
# ps axjf
# ps axms
# ps axZ
Można użyć komendy ps do uzyskania wskazanych parametrów procesów, łącznie z własnym
opisem i określeniem wielkosci pola, na którym będą zapisywane:
# ps -eo pid:10,tid,class,rtprio,ni,pri,psr:5,pcpu:5,stat:5,wchan:24,comm
# ps -eo uid=user_id,pid=process_id,comm=command_name
Jeśli są uruchomione/wstrzymane jakieś procesy, to można nimi zarządzać poprzez komendy
jobs, fg, bg.
Jaki sens mają parametry guid i sid? Jakim procesom odpowiadają te wartości?
Można się o tym przekonać wykonując poniższe komendy i analizując dokładnie wyniki
działania komendy ps:
# ls /usr/bin | more &
# vi xxx &
# ps -elf| grep a | more &
# ps -o uid,pid,pgid,sid,stat,cmd
Zob. także Procesy, procesy lekkie, wątki jądra i ich stany.
Co oznacza parametr PRI? prio=priotytet wg jądra (zob. /proc/PID/sched).
proces/wątek |
prio |
top/htop |
ps -eo pri |
ps -eo rtprio |
ps -el |
nice |
migration |
0 |
RT |
139 |
99 |
-40 |
|
kworker |
100 |
0 |
39 |
60 |
-20 |
|
bash |
120 |
20 |
19 |
80 |
0 |
|
khugepaged |
139 |
39 |
0 |
99 |
19 |
komenda |
prio <100 |
prio >= 100 |
top/htop |
PRI= RT |
PRI= prio - 100 |
ps -eo pri |
PRI= 139 - prio |
PRI= 139 - prio |
ps -el |
PRI= prio - 40 |
PRI= prio - 40 |
Wraz z wprowadzeniem jądra 2.6.23 (10/2007) planista O(1) został zastąpiony planistą całkowicie sprawiedliwym (CFS, Completely Fair Scheduler), który przydziela kwanty czasu zmiennej długości temu zadaniu (procesowi), które go najbardziej potrzebuje; zob. https://en.wikipedia.org/wiki/Completely_Fair_Scheduler.
Zadania przydzielane są do klas, w których obowiązuje wspólna polityka przydziału CPU. W klasie fair możemy mieć zadania typu:
SCHED_NORMAL (zw. także SCHED_OTHER) – polityka przydziału dla zwykłych zadań
SCHED_BATCH – rzadsze wywłaszczanie, zadania wykonują się dłużej, lepsze wykorzystanie pamięci podręcznej procesorów; polityka właściwa dla zadań wsadowych
W klasie idle:
SCHED_IDLE – polityka przydziału słabsza, niż dla zadań ‘nice 19’; zadanie jest wykonywane, kiedy praktycznie procesor nie ma innych zadań do wykonania
W klasie real time:
SCHED_FIFO
SCHED_RR.
Od wersji 3.14 jest także dostępna klasa DEADLINE (zob. https://en.wikipedia.org/wiki/SCHED_DEADLINE).
Do nadawania i zmiany prorytetów służy komenda chrt, a do zmiany pozmiomów uprzejmości
– nice|snice.
Przykłady zmiany priorytetów procesów:
# chrt -b -p 0 PID
# chrt -r -p 99 PID
# chrt -r -p 98 PID
# chrt -p PID
# chrt -b -p 0 PID
# renice +19 PID
# renice -20 PID
# nice -n +19 top -d .5
Sygnały to jeden z mechanizmów komunikacji międzyprocesowej używany w systemach linuksowych (ogólnie uniksopodobnych). Sygnały są krótkimi wiadomościami, które można wysyłać do procesu lub grupy procesów. Z każdym sygnałem jest związana jego nazwa i numer (zależne od platformy). Jest to mechanizm zarządzania procesami dostępny w trybie użytkownika. Sygnały informują proces o wystąpieniu określonego zdarzenia i powodują, że proces wykonuje zawartej w kodzie procesu funkcję obsługi danego sygnału.
Pełną listę sygnałów można znaleźć na stronach podrecznika systemowego (man 7 signal)
lub wykonując komendę kill -l.
Do zarządzania procesami poprzez sygnały używa się następujących komend: pgrep,
pkill, skill, killall.
W celu wyprobowania działania tych komend należy utworzyć zestaw procesów wykorzystując do
tego takie skrypty jak create2kill1.sh (w trybie
tekstowym) oraz
create2kill2.sh (w trybie graficznym).
Po uruchomieniu skryptu (np. create2kill1.sh start) można łatwo sprawdzić, jakie
procesy zostały utworzone (create2kill1.sh status) i które są wybierane przy
zastosowaniu komend:
# pgrep [-l] proc
# pgrep [-l] procA|B
# pgrep [-l] 111|222
# pgrep [-l] [-f] num
# pgrep [-l] [-f] num=
# pgrep [-l] [-f] 12:26
Uwaga! Jeśli w przykładach pojawia się ciąg znaków postaci hh:mm, to trzeba go zastąpić właściwym czasem utworzenia procesów.)
Stosując odpowiednie wyrażenie regularne można spowodować usunięcie wybranego procesu.
Kilka dalszych przykładów:
# pgrep -f './111procA'
# pgrep [-l] '[12]proc'
# pgrep [-l] '[:digit:]{3}proc'
# pgrep [-l] '[ [:digit:] ]{3}proc'
# pgrep [-l] '[ [:digit:] ]{2}proc'
# pgrep [-l] '^[ [:digit:] ]{2}proc'
# pgrep [-l] '^[ [:digit:] ]{3}proc'
# pgrep -l '2.rocA'
# pgrep -l '2p.rocA'
# pgrep -l '2p.ocA'
# pgrep -l '2.....B'
# pgrep '\./111procA'
# pgrep -f '\./111procA'
# pgrep -f '\.\/111procA'
# pgrep -f '.\/111procA'
# pgrep -f '../111procA'
# pgrep -f './111procA'
# pkill -f './111procA'
# pgrep '11:42'
# pgrep -f '11:42'
# pgrep -t pts/0
Zob. także Killing processes that don’t want to die https://lwn.net/Articles/754980/.
System operacyjny pozwala na kontrolę zasobów zużywanych przez poszczególne
procesy. Powłoka bash udostępnia komendę ulimit, dzięki której można kontrolować
dostęp procesów do zasobów (man bash). Rozróżnia się ograniczenia miękkie i twarde.
Użytkownik może modyfikować ograniczenia twarde tylko ``w dół’’, a ograniczenia miękkie
``w dół’’ i ``w górę’’, ale tylko do wielkości wyznaczonej przez ograniczenia sztywne.
Jeśli twarde ograniczenie nie jest ustalone w /etc/security/limits.conf, a ulimit -H -t
pokazuje unlimited, to nie można go zmienić z poziomu użytkownika, gdyż trzeba
jednocześnie zmienić twarde i miękkie ograniczenie. Jeśli jednak użytkownik określi
miękkie ograniczenie, np. ulimit -S -t 1000, to zadziała także komenda ulimit -H -t
1000. Prawidłowa kolejność jest następująca:
# ulimit -a
# ulimit -aH
# ulimit -aS
# ulimit -t 1000
# ulimit -aH|S
# ulimit -St 1100
# ulimit -St 200
# ulimit -St 500
# ulimit -Ht 400
# ulimit -St 200
# ulimit -Ht 300
Ograniczenia H i S muszą być tak modyfikowane, aby nigdy ograniczenie twarde nie przyjmowało wartości mniejszej od ograniczenia miękkiego.
Zob.
W celu zaobserwowania przekierowań należy porównać i przeanalizować działania poniższych komend:
# ls -l /etc/hosts /etc/passwdd
ls: cannot access /etc/passwdd: No such file or directory
-rw-r--r-- 1 root root 4068 maj 20 17:43 /etc/hosts
# ls -l /etc/hosts /etc/passwdd > ls.lst
ls: cannot access /etc/passwdd: No such file or directory
# ls -l /etc/hosts /etc/passwdd 1> ls.lst
ls: cannot access /etc/passwdd: No such file or directory
# ls -l /etc/hosts /etc/passwdd 2> ls.lst
-rw-r--r-- 1 root root 4068 maj 20 17:43 /etc/hosts
# ls -l /etc/hosts /etc/passwdd >& ls.lst
Jak się ma zawartość pliku ls.lst do komunikatów wyświetlanych na konsoli?
Uwaga! Przy wykonywaniu poniższych komend trzeba pamiętać, żeby przed wykonaniem kolejnej usuwać pliki ls.lst i ls.err.
# ls -l /etc/hosts /etc/passwdd 1> ls.lst 2>ls.err
# cat ls.err
# ls -l /etc/hosts /etc/passwdd 1> ls.lst 2>&1
# cat ls.lst
ls: cannot access /etc/passwdd: No such file or directory
-rw-r--r-- 1 root root 1910 Dec 10 19:26 /etc/hosts
# ls -l /etc/hosts /etc/passwdd 2>&1 1> ls.lst
ls: cannot access /etc/passwdd: No such file or directory
Co zawierają pliki ls.lst i ls.err? Dlaczego w ostatnim przykładzie błędy są kierowane na terminal?
Wielokrotna zmiana przekierowania:
# ls -l /etc/hosts /etc/passwdd 1>ls1.lst 1>ls2.lst
Jakiej długości są oba pliki? W jakiej kolejności wyprowadzane są komunikaty?
Poniższe komendy są równoważne
# ls -l /etc/hosts /etc/passwdd 1>ls.lst 2>&1
# ls -l /etc/hosts /etc/passwdd 2>&1 1>ls.lst 2>&1
# cat ls.lst
ls: cannot access /etc/passwdd: No such file or directory
-rw-r--r-- 1 root root 2073 kwi 4 10:40 /etc/hosts
Poniższe także, ale dają inny wynik
# ls -l /etc/hosts /etc/passwdd 2>&1 2>ls.lst 1>ls.lst
# ls -l /etc/hosts /etc/passwdd 2>ls.lst 1>ls.lst
# cat ls.lst
-rw-r--r-- 1 root root 2073 kwi 4 10:40 /etc/hosts
rectory
Z porównania wynika, że najpierw wyprowadzana jest zawartość bufora związanego z deskryptorem 2, a dopiero później – z deskryptorem 1.
Korzystanie z niestandardowych deskryptorów plików:
Jak utworzyć plik o zerowej długości lub wyzerować już istniejący plik?
# : > hosts
Jak powiązać deskryptor pliku z plikiem?
# cp /etc/hosts hosts
# exec 10<hosts
Ile razy można wykonać komendę cat <&10?
Dane z deskryptora 10 można czytać wiersz po wierszu:
# exec 10<hosts
# read line <&10
# echo $line
# read line <&10
# echo $line
W każdej chwili można deskryptor zamknąć:
exec 10>&-
read line <&10
Porównać komendę cat /etc/hosts |less z komendami
# 0</etc/hosts less
# </etc/hosts less
Znaczenie symboli &-, <&-, 2>&-:
zamykanie deskryptora pliku n do odczytu: n<&-
zamykanie STDIN: 0<&-, <&-
zamykanie deskryptora n pliku do zapisu: n>&-
zamykanie standardowego wyjścia: 1>&-, >&-
W jednym terminalu mamy sesję basha o numerze np. 4717 (echo $$). W drugim
terminalu można obserwować pliki związane z tym procesem przy użyciu komendy: lsof -a -p 4717 -d0,1,2,3,10
(komendę lsof trzeba wywoływać jako użytkownik ‘root’!).
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 4717 jkob 0u CHR 136,13 0t0 16 /dev/pts/13
bash 4717 jkob 1u CHR 136,13 0t0 16 /dev/pts/13
bash 4717 jkob 2u CHR 136,13 0t0 16 /dev/pts/13
Wygodniej jest te obserwacje robić dla komendy ping wywoływanej z różnymi przekierowaniami:
# ping localhost
# lsof -a -p `pgrep ping` -d0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ping 12543 root 0u CHR 136,28 0t0 31 /dev/pts/28
ping 12543 root 1u CHR 136,28 0t0 31 /dev/pts/28
ping 12543 root 2u CHR 136,28 0t0 31 /dev/pts/28
# ping localhost > ping.out
# lsof -a -p `pgrep ping` -d0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ping 13259 root 0u CHR 136,28 0t0 31 /dev/pts/28
ping 13259 root 1w REG 8,17 810 139202 /root/ping.out
ping 13259 root 2u CHR 136,28 0t0 31 /dev/pts/28
# ping localhost 1> ping.out 2>ping.err
# lsof -a -p `pgrep ping` -d0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ping 13474 root 0u CHR 136,28 0t0 31 /dev/pts/28
ping 13474 root 1w REG 8,17 601 139202 /root/ping.out
ping 13474 root 2w REG 8,17 0 173991 /root/ping.err
# ping localhost 1> ping.out 2>&1
# lsof -a -p `pgrep ping` -d0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ping 13915 root 0u CHR 136,28 0t0 31 /dev/pts/28
ping 13915 root 1w REG 8,17 394 139202 /root/ping.out
ping 13915 root 2w REG 8,17 394 139202 /root/ping.out
# ping localhost 2>&1 1>ping.out
# lsof -a -p `pgrep ping` -d0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ping 14122 root 0u CHR 136,28 0t0 31 /dev/pts/28
ping 14122 root 1w REG 8,17 950 139202 /root/ping.out
ping 14122 root 2u CHR 136,28 0t0 31 /dev/pts/28
Do obserwacji przekierowań można także wykorzystać komendę xargs.
Potok jest połączony ze standardowym wyjściem:
# ls -la /etc/passwdd /etc/hosts | xargs -I{} echo '###' {} '###'
Standardowe wyjście błędów jest kopią wyjścia standardowego:
# ls -la /etc/passwdd /etc/hosts 2>&1 | xargs -I{} echo '###' {} '###'
Któryś ze strumieni wyjściowych jest usuwany:
# ls -la /etc/passwdd /etc/hosts 1>/dev/null | xargs -I{} echo '###' {} '###'
# ls -la /etc/passwdd /etc/hosts 2>/dev/null | xargs -I{} echo '###' {} '###'
Manipulacji na deskryptorach można dokonywać w dowolnym miejscu komendy:
# 2>&1 ls -la /etc/passwdd /etc/hosts | xargs -I{} echo '###' {} '###'
# ls -la /etc/passwdd /etc/hosts 2>&1 | xargs -I{} echo '###' {} '###'
Potok jest połączony ze standardowym wyjściem i standardowym wyjściem dla błędów:
# ls -la /etc/passwdd /etc/hosts |& xargs -I{} echo '###' {} '###'
Żadna wiadomość nie jest przekazywana do procesu xargs:
# 1>&2 ls -la /etc/passwdd /etc/hosts | xargs -I{} echo '###' {} '###'
# ls -la /etc/passwdd /etc/hosts 1>&2 | xargs -I{} echo '###' {} '###'
W przypadku zastosowania |& sprzęganie strumieni zachodzi inaczej (dlaczego?):
# ls -la /etc/passwdd /etc/hosts 1>/dev/null |& xargs -I{} echo '###' {} '###'
# ls -la /etc/passwdd /etc/hosts 2>/dev/null |& xargs -I{} echo '###' {} '###'