====== 6. Lucrul cu procese ======
Acțiunile sunt executate la nivelul sistemului de fișiere prin procese. Rularea unei comenzi înseamnă crearea unui proces în sistemul de operare, proces care execută acțiunea indicată de executabilul din care a luat naștere. Procesele sunt entități active care consumă resurse la nivelul sistemului de operare, cele mai importante fiind procesor, memorie și diverse forme de input/output.
===== Subiecte abordate =====
* Procese, operații cu procese, planificarea proceselor
* Investigarea proceselor
* Foreground/background
==== Best practices ====
* În general, nu se prelucrează output-ul comenzii ''ps''
* Selecția de informații pe orizonatală (ce procese?) față de selecția pe verticală (ce atribute?)
* ''\time'' vs ''time''
* ''killall'' vs ''pkill''
==== Utilitare folosite ====
* ''ps'', ''pstree'', ''top'', ''htop'', ''/proc'', ''pidof''
* ''kill'', ''pkill'', ''pgrep''
* ''time'', ''lsof''
* ''tmux''
===== Resurse utile =====
* TODO
* TODO
===== Exerciții =====
==== Demo-uri ====
=== Lucrul cu procese ===
Pentru a afla informații despre procese se poate folosi utilitarul {{{ps}}}.
Pentru a afișa toate procesele ce rulează în respectivul moment, rulați comanda:
ps -e
Observați ce informații furnizează rularea numai cu acest parametru (capul de tabel).
Selecția se poate face după o serie de criterii (utilizatorul ce deține procesul, comanda cu care acest a fost lansat, PID etc.). Pentru a selecta doar procesele ce aparțin utilizatorului {{{student}}}, executați comanda:
ps -u student
Rulați comanda:
ps -e -F
Observați în ce mod s-a modificat capul tabelului.
Se poate alege ce câmpuri să fie afișate (PID, utilizator, comandă, memorie ocupată etc.). Pentru a afișa PID-ul, utilizatorul, procentul din memorie utilizat și comanda cu care a fost lansat un proces, rulați comanda:
ps -e -o pid,user,%mem,cmd
Opțiunile de selecție se pot combina cu cele de formatare. De exemplu, pentru a afișa PID-ul și memoria ocupată de procesul cu PID-ul 1, executați:
ps -p 1 -o pid,%mem
Lista se poate sorta după un criteriu dat. De exemplu, putem sorta ascendent lista tuturor proceselor din sistem după PID:
ps -A -o pid,%mem --sort +pid
Pentru a sorta descendent se pune {{{-}}} (minus) în loc de {{{+}}} (plus) în fața criteriului de sortare.
Deschideți o instanță de editor ''emacs''.
Aflați PID-ul acestuia și, din alt terminal, opriți procesul:
kill -SIGSTOP PID
Această comandă are același efect ca și combinația de taste {{{Ctrl + z}}}. Pentru a termina complet procesul, se pot folosi semnalele {{{SIGTERM}}} sau {{{SIGKILL}}}.
==== Exerciții cu procese ====
Obțineți o listare arborescentă a proceselor folosind comanda {{{pstree}}} și apoi obţineţi o listare similară arborescentă) folosind comanda {{{ps}}}.
Căutați după șirul //forest// în pagina de manual a comenzii ''ps''.
Afișați procesele care **nu** aparțin utilizatorului ''student''.
Căutați după șirul //negates// în pagina de manual a comenzii ''ps''.
Afișați pentru toate procesele următoarele atribute: PID, comanda cu care a fost lansat, niceness, PID-ul părinteluiși sortați descendent lista după PID-ul părintelui.
Căutați în pagina de manual a comenzii ''ps'' secțiunea //STANDARD FORMAT SPECIFIERS//.
Verificați faptul că procesul ''init'' (PID-ul 1) adoptă procesele orfane. Deschideți un nou terminal și din acesta porniți o instanță de {{{xterm}}} în background. Din instanța de {{{xterm}}}, porniți o a doua instanță de {{{xterm}}} în background. Din terminal afișați lista proceselor în format arborscent, afișând și PID-ul fiecărui proces.
Pentru afișare în format arborescent folosiți comanda ''pstree''.
Identificați PID-ul primei sesiuni de {{{xterm}}} și trimiteți procesului respectiv semnalul SIGKILL. Identificați procesul părinte al celei de-a doua sesiuni de {{{xterm}}}.
Folosiți comanda {{{free}}} pentru a obține detalii despre memoria ocupată.
''free'' poate fi folosit și ca un utilitar pentru monitorizarea continuă a stării memoriei. Identificați un parametru care produce output o dată la 2 secunde.
Folosiți comanda {{{uptime}}} pentru a determina de cât timp funcționează sistemul. Identificați aceleași valori cu ajutorul comenzii {{{top}}}.
Să se afișeze toate fișierele dechise de procesul {{{bash}}} pornit de utilizatorul student.
Pentru procesele de mai sus afișați PID-ul, comanda completă (cale completă cu parametri), timpul de rulare pe procesor, memoria RAM consumată (RSS -- //resident set size//). Pentru a selecta doar anumite atribute ale unui proces folosiți comanda ''ps'' cu parametrul ''-o'' urmat de opțiunile specifice.
Urmăriți și pagina de manual a comenzii ''ps'' secțiunea ''STANDARD FORMAT SPECIFIERS''.
Afișați cele mai consumatoare de memorie 5 procese din sistem care **nu** aparțin utilizatorului ''root''.
Pentru afișarea de mai sus, folosiți opțiunea de ascundere a header-ului în afișarea comenzii ''ps''.
Folosiți comanda {{{uptime}}} pentru a determina de cât timp funcționează sistemul. Identificați aceleași valori cu ajutorul comenzii {{{top}}}.
==== Demo: Investigarea proceselor ====
Comanda {{{lsof}}} afișează descriptorii de fișier ai unui proces. Rularea acesteia fără niciun argumente afișează o listă de fișiere care aparține tuturor proceselor deschise:
lsof
Pentru a lista procesele care au deschis fișiere dintr-un anumit director:
lsof +D /dev/
Pentru a lista procesele pornite de un anumit utilizator:
lsof -u "student"
Pentru a lista procesele care încep cu un string:
lsof -c "ssh"
Vizualizarea descriptorilor de fișier folosind comanda ''lsof'' pentru procesul ''sleep'' din fiecare din comenzile de mai jos
sleep 30 > a.txt
sleep 30 < a.txt
sleep 30 < a.txt > b.txt 2> c.txt
cat | sleep 30 | cat
==== Demo: Rularea în background ====
Pornire proces ''emacs'' și folosire ''Ctrl+z'' și ''bg'' pentru rulare în background.
Pornire proces ''emacs'' direct în background.
==== Procesele unui utilizator ====
Dorim să lucrăm cu grupuri de procese care țin de un utilizator.
Pe un tab nou de terminal adăugăm utilizatorul ''ana'' folosind comenzile
$ sudo su
# adduser ana
[...]
# exit # sau puteti folosi combinatia de taste Ctrl+d
$
În acel tab nou ne autentificăm ca utilizatorul ''ana'' folosind comanda
$ su - ana
În cel nou tab, din contul utilizatorului ''ana'', porniți în background mai multe procese: ''sleep'', ''emacs'', ''gedit''.
Din primul tab, folosiți, ca ''root'', ''pkill'' pentru o încheia execuția proceselor utilizatorului ''ana''; adică rulați ''sudo pkill ...'' (cu ce opțiuni sunt utile). Este posibil să fie necesar să folosiți semnalul ''SIGKILL'' ca să fie garantată încheierea execuției.
==== Procesele unui terminal ====
Pe un tab nou de terminal porniți în background procese ca utilizatorul ''root'', ''student'' și ''ana''.
În acel tab aflăm care este identificatorul terminalului curent folosind comanda
$ tty
Din primul tab, folosiți, ca ''root'', ''pkill'' pentru o încheia execuția proceselor de pe al doilea terminal; adică rulați ''%%sudo pkill ...%%'' (cu ce opțiuni sunt utile). Este posibil să fie necesar să folosiți semnalul ''SIGKILL'' ca să fie garantată încheierea execuției.
==== Folosirea tmux ====
Porniți într-un ecran ''tmux'' un tracker BitTorrent, un server HTTP Python, un editor Vim sau Emacs și încă un ecran pentru comenzi.
Pentru pornirea ''tmux'' folosiți comanda
tmux
Pentru a deschide ecrane noi în ''tmux'' folosiți combinația de taste ''Ctrl+b'' și apoi separat ''c''. Pentru a tranzita între ferestre folosiți combinațiile de taste ''Ctrl+b'' urmat de ''n'' și ''Ctrl+b'' urmat de ''p''. Pentru a închide un ecran închideți shell-ul folosind ''Ctrl+d'' sau ''exit'' sau ''logout''.
Pentru a vă detașa de ''tmux'' folosiți combinația de taste ''Ctrl+b'' urmat de ''d''. Pentru a vă reatașa la ''tmux'' folosiți comanda
tmux attach
Pentru a porni un server HTTP Python folosiți comanda
python -m SimpleHTTPServer
==== Exerciții cu redirectări ====
Ca utilizatorul student și folosind ''sudo'', ''echo'' scrieți valoarea ''1'' în fișierul ''/proc/sys/net/ipv4/ip_forward''. Trebuie să folosiți ''tee''. Gândiți-vă cum construiți comanda.
Pentru a afișa fișierele deschise de comanda ''ls -l'' folosiți construcția
strace -e open ls -l
Redirectați ieșirea standard a comenzii (//standard output//) comenzii în fișierul ''ls.out'' iar ieșirea de eroare standard a comenzii (//standard error//) în fișierul ''strace.err''.
Comanda ''strace'' menține ieșirea comenzii rulate la //standard output// în vreme ce output-ul său este furnizat la //standard error//.
În mod similar comenzii ''strace'' comanda ''time'' măsoară timpul de rulare a unei comenzi și alte informații. Pentru a rula comanda ''time'' din sistem (există și o comandă ''time'' internă shell-ului), folosiți construcția
/usr/bin/time -v pidof bash
Comanda de mai sus afișează informații legate de rularea comenzii ''pidof bash''.
Redirectați ieșirea standard a comenzii (//standard output//) comenzii în fișierul ''pidof.out'' iar ieșirea de eroare standard a comenzii (//standard error//) în fișierul ''time.err''.