Laborator 04 - Utilizatori și procese

Cheatsheet utilizatori

Comandă Descriere scurtă
sudo execută o comandă cu drepturi de utilizator privilegiat
su schimbă utilizatorul cu care suntem autentificați
id afișează id-ul și grupurile din care face parte un utilizator
finger afișează un sumar despre un anumit utilizator
whoami afișează utilizatorul curent (cu care suntem autentificați)
who lista de utilizatori autentificați la un moment dat
passwd schimbă parola unui utilizator
adduser adaugă un utilizator
deluser șterge un utilizator
usermod modifică informații despre un utilizar (exemplu: grupul din care face parte)
addgroup adaugă un grup de utilizatori
delgroup șterge un grup de utilizatori

Cheatsheet procese

Comandă Descriere scurtă
ps snapshot al proceselor curente
pgrep Afișează PID-ul proceselor cu nume dat ca argument. Se pot folosi opțiuni pentru filtrare (exemplu: după numele utilizatorului care a deschis respectivul proces)
top utilitar echivalent lui Windows Task Manager, in Linux. Există și htop, mai avansat și cu mai multe posibilități
pstree ierarhia de procese
kill trimite un semnal unui proces. Folosind comanda kill -l putem vedea semnalele care pot fi trimise
killall omoară toate procesele cu același nume
pkill caută un proces după nume și îi transmite un semnal
jobs afișează procesele pornite în background

Foreground and background procese

Stările unui proces

Suport laborator

Demo

Utilizatori

[1] Utiliatori privilegiați si neprivilegiați (id, finger, whoami)

În general, pe un sistem Linux, sunt două ierarhii de utilizatori:

  • neprivilegiați - nu pot modifica starea sistemului, nu pot realiza modificări ce afectează alți utilizatori
  • privilegiați - spre exemplu utilizatorul root

Utilizatorul root este prezent, în general, pe orice sistem Linux, rolul său fiind de administrare și gestionarea celorlalți utilizatori.

Nu este recomandat să folosiți sistemul folosind acest utilizator decât pentru strictul necesar. De multe ori este suficientă utilizarea comenzii sudo.

[2] Schimbarea utilizatorului curent (su)

Câteodată este necesar să schimbăm utilizatorul cu care suntem autentificați într-un altul (de exemplu în root pentru a realiza un task administrativ). Pentru aceasta folosim comanda su (switch user). Haideți să vedem cum o folosim.

[3] Drepturi pentru anumite comenzi (sudo)

Să presupunem că pe un sistem avem 100 de utilizatori și vrem ca toți să aibă drepturile necesare instalării de noi pachete, dar să nu poată adăuga/șterge alți utilizatori. Pe lângă faptul că ar fi foarte foarte nesigur ca 100 de persoane să știe parola contului de root, ar trebui să ne bazăm pe încrederea că ei nu vor face altceva decât să instaleze pachete. Soluția acestei probleme este comanda sudo.

[4] Schimbarea parolei (passwd)

Pentru a schimba parola utilizatorului curent folosim comanda passwd, fără argumente. De asemenea, dacă dorim schimbarea parolei altui utilizator, îi putem oferi comenzii passwd numele acestuia ca parametru. Mai departe vom vedea un exemplu de cum facem acest lucru.

[5] Gestiunea utilizatorilor (adduser/deluser)

Acum că știm cum vedem informații despre un utilizator, cum schimbăm o parolă sau cum schimbăm utilizatorul curent, hai să vedem cum adăugăm utilizatori noi sau cum ștergem un utilizator dintre cei existenți. Pentru aceasta vom folosi comenzile adduser și deluser.

Cele două comenzi sunt de fapt niște scripturi wrapper scrise în Perl prezente, în general, numai pe distribuții bazate pe Debian (cum ar fi Ubuntu). Comenzile pe care le apelează ele în spate sunt useradd și userdel.

[6] De reținut!

La orice moment de timp, așa cum te uiți în oglinda retrovizoare a unei mașini și știi mereu ce ai în spate, trebuie să știi trei lucruri, mai ales în contextul folosirii mașinilor virtuale:

  • care este hostname-ul (pe ce sistem te afli). Comenzi utile: cat /etc/hostname, hostname
  • care este username-ul (cu ce utilizator ești autentificat): whoami, id (fără parametrii),
  • care este working directory-ul (în ce director lucrezi): pwd

Toate informațiile de mai sus se găsesc în prompt-ul terminalului: username@hostname:working-directory.

E important să reținem că urmărirea prompt-ului este o convenție. Acesta poate fi schimbat foare ușor folosind bashrc. Detalii puteți găsi pe cyberciti.

Procese

[1] Vizualizarea proceselor din sistem (ps, pstree, top, htop)

Ierarhia de procese în formă arborescentă putem vizualiza folosind pstree (similar cu tree de la sistemul de fișiere)

Folosind ps fără nici un parametru vizualizăm procesele din shell-ul curent asociate utilizatorului curent. Tot cu ps putem vizualiza un snapshot al tuturor proceselor. Aceasta se poate obține folosind două variante ale comenzii:

student@midgard:~$ ps aux
student@midgard:~$ ps -ef

Un utilitar echivalent lui Windows Task Manager pentru vizualizarea în timp real a proceselor care rulează, în linie de comandă, este htop.

student@midgard:~$ htop

[2] Foreground & Background (&, fg, bg, jobs)

Porniți un proces sleep 1000 (nu face nimic, e deschis, în starea sleep timp de 1000 de secunde). Haideți să le transmitem niște semnale prin combinații de taste, să vedem ce observăm în Bash. De exemplu:

Taste Semnificație
Ctrl+C trimite SIGINT
Ctrl+Z trimite SIGSTOP
Ctrl+\ trimite SIGQUIT
student@midgard:~$ sleep 1000
^Z
[1]+  Stopped                 sleep 1000
student@midgard:~$ bg
[1]+ sleep 1000 &
student@midgard:~$ jobs
[1]-  Running                 sleep 1000 &
student@midgard:~$ fg 1
sleep 1000
^C
student@midgard:~$ 
student@midgard:~$ ps
  PID TTY          TIME CMD
13038 pts/0    00:00:00 bash
16827 pts/0    00:00:00 ps

Creăm un proces care va rula mult timp (căutăm să aflăm dimensiunea tuturor fișierelor), apoi aducem în starea stopped, apoi în running, apoi ar trebui să apară și un Exit când termină. Cu jobs putem afla procesele running din fundal. Detalii aflați din help jobs :-)

student@midgard:~$ sudo du -hs /
[sudo] password for student:
^Z
[1]+  Stopped                 sudo du -hs /
student@midgard:~$ bg
[1]+ sudo du -hs / &
student@midgard:~$ jobs
[1]+  Running                 sudo du -hs /
student@midgard:~$ 3.4G   /
[1]+  Exit 1                  sudo du -hs /

[3] Semnale (kill)

Un utilizator poate trimite un semnal unui proces folosind comanda kill! Este foarte important să înțelegem că nu este scopul principal omorârea de procese folosind kill. O listă a tuturor semnalelor posibile ce pot fi trimise aflăm prin

student@midgard:~$ kill -l   

Noi ne vom concentra pe distrugerea proceselor, în următorul demo.

Haideți să pornim un proces, în fundal, care caută toate fișierele în /:

student@midgard:~$ find / -name '*' &

Deschidem un alt terminal. Căutăm identificatorul procesului anterior. Nu folosi top, care e interactiv și ne afișază toate procesele în timp real, pentru că ne interesează doar procesul sau procesele de find:

student@midgard:~$ pgrep find
2628

Pe sistemele voastre va varia PID-ul (Process ID).

Ne dăm seama că procesul consumă resurse (operații pe hard disk) inutile. Dorim să îl terminăm:

student@midgard:~$ kill 2628

Implicit, kill trimite semnalul 15) SIGTERM: acesta se asigură că toate resursele folosite de proces (cum fișiere deschise) sunt închise corect și abia apoi e închisă aplicația (e omorât procesul). Semnalul 9) SIGKILL e preocupat în principal de închiderea aplicației direct. Comanda de mai sus e similară cu

student@midgard:~$ kill -15 2628

Repornim procesul find. De data asta folosim o comandă care nu implică determinarea PID-ului:

student@midgard:~$ pkill find

Instalați pe sistemele voastre chromium-browser, dacă acesta nu e deja instalat. Deschideți browserul și 10 tab-uri în care să intrați pe diverse site-uri. Deteminați PID-urile tutror proceselor pornite de chromium-browser

Dorim să omorâm toate aceste procese. Pentru aceasta putem folosi în loc de kill PID1 PID2 … PID_N putem folosi mai eficient:

student@midgard:~$ killall chromium-browser

Ce s-a întâmplat cu site-urile care erau deschise?

Exerciții

[0] Pregătire setup laborator (0.5p)

Pentru a descărca fișierele necesare acestui laborator deschidem un terminal (folosim combinația de taste Alt+Ctrl+t) și clonăm repository-ului oficial uso.

Ne asigurăm că suntem în /home/student

Folosim comanda:

student@midgard:~$ git clone https://github.com/systems-cs-pub-ro/uso

În directorul /home/student/uso/lab04 găsim fișierele necesare pentru laboratorul 4.

Utilizatori

[1] Adăugarea de noi utilizatori și de grupuri (2p)

Ca administratori ai infrastructurii IT a școlii de care răspundeți ați primit următorul excel cu nume de utilizatori și grupuri din care trebuie să facă parte, conform cu politica școlii.

Sarcina voastră este să adăugați în sistem grupurile și apoi utilizatorii, utilizatorii să îi înscrieți în grupuri conform cu excelul primit.

De asemenea, trebuie să configurați următoarele parole:

  • Studenții vor avea parola student
  • Profesorii vor avea parola profesor007
  • Adminii vor avea parola admin1234

Pentru cei care sunt în mai multe grupuri simultan alegeți parola mai dificilă (să conțină cifre diferite).

Pentru verificarea adăugării utilizatorilor în sistem trebuie să inspectăm fișierele: /etc/passwd și pentru grupuri /etc/group. De asemenea, pentru a vedea grupurile din care face parte un anumit utilizator (să zicem dan) și totodată existența sa în sistem mai putem folosi comanda:

student@uso~$ id dan

De asemenea, pentru a nu cauta in fisierele /etc/passwd sau /etc/group putem folosi comanda getent ca mai jos pentru verificarea direct a setarilor pentru un user sau un grup:

student@uso~$ getent passwd dan
dan:x:1003:1003:Dan:/home/public/dan:/bin/bash
student@uso~$ getent group gdm
gdm:x:42:

[2] Schimbarea homedir-ului altui utilizator (1p)

Configurați sistemul astfel încât home directory-ul utilizatorului dan în loc de /home/dan să fie /home/public/dan. Creați directorul dacă acesta nu există.

Indicație: Folosim usermod (modify a user account). Căutați după new login directory.

Pentru verificare : Apăsați Ctrl+D pentru a reveni la terminalul în care erați autentificați ca student după care încercați comanda su - dan. Dați pwd și verificați că homedir-ul acestuia e cel configurat cu usermod. Alt mod de a verifica este inspectarea fișierului /etc/passwd și căutând linia care conține dan.

Pentru a ne autentifica cu un anumit utilizator și a ne muta în homedir-ul lui folosim su - dan in loc de simplu su dan

[3a] Drepturi de sudo pentru un utilizator (1p)

Suntem autentificați ca utilizatorul corina și vrem să instalăm un pachet. Observăm totuși că nu avem permisiuni.

corina@midgard:~$ sudo apt-get install tree
[sudo] password for corina: 
corina is not in the sudoers file.  This incident will be reported.

Pentru a acorda drepturi de sudo unui utilizator se folosește comanda visudo. Reveniți la shellul utilizatorului student (Ctrl+D) și tastați comanda:

student@midgard:~$ sudo visudo

Dați drepturi utilizatorului corina de a instala pachete in sistem, fără a i se cere parola. Puteți vedea un exemplu de configurație pe askubuntu.

Verificare: Reautentificați-vă drept corina și încercați din nou să rulați o comandă de instalare de pachete în sistem folosind sudo.

[3b] Drepturi de sudo pentru un grup (1p)

În același mod configurați sistemul astfel încât utilizatorii din grupul profesor să aibă drepturi depline de sudo în sistem.

Autentificați-vă în sistem ca geo și ca răzvan și verificați că funcționează comanda:

geo@uso:~$ sudo apt-get install rig

Asigurați-vă că nu apare eroarea (dacă apare înseamnă că ați greșit configurația din visudo):

(...)
geo is not in the sudoers file. This incident will be reported.
(...)

Procese

[4] Lucrul cu procese în backgroud/foreground (2p)

Mergeți în directorul /home/student/uso/lab04 și rulați scriptul bg-proc.sh:

student@midgard:~$ cd uso/lab04
student@midgard:~$ ./bg-proc.sh 
Tick!
Tock!
Tick!
...

Observăm că procesul rulează la infinit și afișează pe ecran un mesaj din secundă în secundă. Încercăm să rulăm o comandă simplă, spre exemplu ls, dar vedem că ea este ignorată. Acest lucru se datorează faptului că procesul nostru se află în foreground, așa că tot ce tastăm noi se duce practic ca input pentru respectivul proces. Căutați în cheatsheet o combinație de taste ce trimite procesul nostru în background.

Verificăm că procesul există încă. Pentru aceasta tastați comanda ps. Dorim acum să repornim procesul, dar nu mai vrem să fie tot în foreground, ci vrem să avem access și la shell în acest timp. Pentru aceasta folosim comanda bg. Observați că imediat după ce o tastăm au reînceput să apară mesajele pe ecran. Tastați iarăși comanda ls și vedem că de data aceasta ea funcționează aproape așa cum ne așteptăm. Afișează fișierele și directoarele din directorul curent, dar în același timp sunt afișate și mesajele periodice ale procesului nostru.

Fenomenul de mai sus se produce datorită faptului că terminalul nostru este legat la ieșirea (stdout) a două procese, ls și bg-proc.sh. Mai multe detalii despre cele 3 intrări/ieșiri standard ale unui proces puteți găsi aici.

[5] Terminarea unui set de procese (1.5p)

Deschideți atât browser-ul Firefox, cât și browser-ul Chromium. Deschideți câte 5 tab-uri în fiecare browser. Folosind ps, sau mai util pgrep, identificați PID-urile proceselor deschise de cele două browsere.

Folosind htop monitorizați consumul de resurse al acestor procese (e.g. CPU percent usage, RAM usage).

Ce se va întâmpla la rularea următoarei comenzi? Vom pierde toată sesiunea din Firefox?

pkill -f firefox

Folosind PID-urile identificate anterior, trimiteți semnalul SIGINT (2) procesului chrome cu cel mai mare PID. Pierdem toată sesiunea în acest caz? Dar dacă rulăm comanda de mai jos, similar cu cea trimisă lui Firefox?

pkill chromium

Despre pkill puteți citi și în acest articol.

Despre monitorizarea proceselor și trimiterea semnalelor recomandăm acest articol.

[6] Terminarea forțată a unui proces (1p)

Mergeți în directorul /home/student/uso/lab04 și rulați scriptul it-s-a-trap.sh. Eram obișnuiți ca atunci când avem un proces în foreground să-l putem opri cu combinația de taste Ctrl+C, însă observăm că acest lucru nu mai funcționează în cazul procesului nostru.

student@midgard:~/uso/lab04$ ./it-s-a-trap.sh 
Still running . . . 
Still running . . . 
^CIT's A TRAP!
Still running . . . 
^CIT's A TRAP!
...

Porniți un alt terminal și aflați PID-ul procesului folosind comanda ps. După ce l-ați aflat, haideți să încercăm să-l omorâm așa cum am făcut cu celălalt proces la exercițiul precedent.

student@midgard:~$ ps U student
  PID TTY      STAT   TIME COMMAND
 1545 ?        Sl     0:00 /usr/bin/gnome-keyring-daemon --daemonize --login
 12361 pts/25   S+     0:00 /bin/bash ./it-s-a-trap.sh
12371 pts/25   S+     0:00 sleep 3
12372 pts/26   R+     0:00 ps U student
student@midgard:~$ kill 12361

încercați să-i trimiteți diferite semnale, de exemplu SIGTERM, SIGINT, SIGQUIT și observați ce se întâmplă. Cum reacționează procesul la ele?

Pentru a afișa lista de semnale disponibile folosim comanda:

student@midgard:~$ kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
student@midgard:~$ kill -SIGTERM 12361
student@midgard:~$ kill -SIGINT 12361
student@midgard:~/uso/lab04$ ./it-s-a-trap.sh 
Still running . . . 
IT's A TRAP!
Still running . . . 
IT's A TRAP!
Still running . . . 
Still running . . . 
...

S-ar părea că procesul nostru este imun la semnale. Să încercăm și cu semnalul SIGKILL. Trimiteți-i-l și pe acesta. Ce s-a întâmplat cu procesul nostru?

Singurul semnal care nu poate fi interceptat și ignorat de către niciun proces este semnalul SIGKILL, așadar el garantându-ne terminarea procesului. Dezavantajul este însă că procesul va fi terminat brusc, fără a mai realiza nicio procedură de salvarea a stării curente, așa cum se întâmplă în cazul altor semnale precum SIGTERM.

Putem trimite semnale unui proces și doar folosind indexul semnalui, nu neapărat numele lui. Astfel comanda kill -9 $PID este echivalentă cu comanda kill -SIGKILL $PID, de exemplu.

Rețineți că la folosirea kill -9 resursele ocupate de un proces (e.g.: fisiere) e foarte posibil să nu fie eliberate deloc sau să nu fie eliberate corect.

[BONUS #1] Resurse ocupate de un proces [1 karma WoUSO]

Porniți instalarea următorului pachet (are în jur de 1.5 GB) și lăsați instalarea să curgă în terminal:

student@uso:~$ sudo apt-get -y install texlive-full

Deschideți un alt terminal. Încercați să instalați un singur pachet, spre exemplu:

student@uso:~$ sudo apt-get -y install toilet

Ce eroare obținem? Am folosit drepturile privilegiate, iar pachetul există:

E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)
E: Unable to lock the administration directory (/var/lib/dpkg/), is another process using it?
W: Could not lock the cache file; this usually means that dpkg or another apt tool is already installing packages.  Opening in read-only mode; any changes you make to the states of packages will NOT be preserved!

Între timp am uitat de instalarea lungă pornită în fundal în celălalt terminal. Identificați PID-ul procesului care ține resursa /var/lib/dpkg/lock ocupată.

În cazul de față, în Linux, o dată pornită o instalare se pune lock pe o resursă și alte procese care încearcă să pornească o instalare nu mai au voie până când resursa nu e eliberată.

Pentru depanarea problemei noastre cel mai bun utilitar este folosirea lsof (cu ajutorul lui putem identifica ce procese țin deschis un anumit fișier) sau o variantă simplificată, dedicată acestei sarcini: fuser

După ce ați identificat PID-ul procesului care ține ocupată resursa /var/lib/dpkg/lock listați și celelalte fișiere deschise de acel proces folosind procfs.

[BONUS #2] Procese detașate de terminal [1 Karma WoUSO]

Pentru acest exercițiu avem nevoie de pachetul transmission-cli. Îl putem instala folosind comanda

student@midgard:~$ sudo apt-get install transmission-cli

Folosiți Transmission în linie de comandă pentru a descărca mașina virtuală pentru tema de la USO, de aici. Descărcați fișierul .torrent în /home/student/Downloads.

student@midgard:~$ transmission-cli ~/Downloads/USO-Mint-VM.ova.torrent

Dintr-un alt terminal determinați PID-ul acestui proces. Închideți terminalul din interfața grafică (X din colțul din dreapta sus). Căutați din nou procesul după identificator. Ce s-a întâmplat cu procesul nostru transmission-cli tocmai creat? Care credeți că este cauza?

Deschideți din nou un terminal, dar de data folosiți-vă de comanda nohup (man nohup) pentru a lansa procesul transmission-cli pentru descărcarea temei de la USO. Închideți din nou terminalul din interfața grafică. Observați că procesul rămâne în viață. Determinați PID-ul acestui proces.

Ce fel de semnal se generează atunci când închidem terminalul și pe care a doua oară procesul transmission-gtk îl ignoră?

[BONUS #3] Trimiterea de semnale unui proces [1 karma WoUSO]

Mergeți în directorul /home/student/uso/lab04 unde găsiți scriptul batman.sh. Rulați-l. Procesul interceptează toate semnalele cu indecși de la 1 la 13, mai puțin 9 (din motive evidente). De fiecare dată când primește un semnal cu indexul între 1 și 13 el afișează pe ecran un caracter. Mai jos aveți maparea dintre indecșii semnalelor și caracterul afișat:

Index semnal Caracter
1 o
2 u
3 c
4 d
5 e
6 z
Index semnal Caracter
7 s
8 h
10 (space)
11 r
12 k
13 l

Într-un alt terminal aflați pid-ul procesului și trimiteți-i semnale astfel încât procesul să afișeze pe ecran șirul de caractere uso rullz.

Sumar. Cuvinte cheie

  • Utilizator (user): cont cu care ne putem autentifica pe un sistem. Sunt identificați printr-un UID User ID
  • UID-ul lui root este 0. PID-ul lui init este 1.
  • Adăugare utilizatori: adduser, deluser. Mai generale: useradd, userdel.
  • Modificarea proprietăților unui utilizator: usermod
  • Schimbă parola: passwd
  • Execută o comandă cu drepturi elevate: sudo
  • Proces: executabil care rulează în momentul de față. Mai multe rulări, mai multe procese (fiecare cu al său).
  • PID: Process ID
  • PPID: Parent Process ID
  • Vizualizarea proceselor ce rulează la un moment dat: ps, pstree
  • Vizualizarea proceselor ce rulează la un moment dat într-un mod interactiv: top, htop
  • Trimiterea de semnale unui process: kill. kill -9 $PID pentru a fi siguri că procesul moare.
  • Rularea de procese în background: &. Spre exemplu
    student@midgard:~$ firefox & 
  • Terminarea tuturor proceselor pornite din același executabil: killall, pkill
uso-ac/laboratoare/laborator-04.txt · Last modified: 2017/10/15 22:01 by giorgiana.vlasceanu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0