This is an old revision of the document!
Pentru a deschide un terminal nou:
Scurtătură | Descriere |
---|---|
Ctrl+Alt+t | pentru a deschide o nouă fereastră de terminal |
Puteți folosi următoarele scurtături în terminal:
Scurtătură | Descriere |
---|---|
Ctrl+Shift+t | pentru a deschide un nou tab |
Ctrl+PageDown | pentru a merge la tab-ul următor |
Ctrl+PageUp | pentru a merge la tab-ul precedent |
Alt+<index> | pentru a sări direct la un tab |
Ctrl+d | pentru a închide un tab (sau comanda exit ) |
Pentru a naviga (scrolling) în cadrul unui terminal, mai ales atunci când o comandă afișează mult text, folosiți următoarele scurtături:
Scurtătură | Descriere |
---|---|
Shift+PgDown | pentru a derula în jos |
Shift+PgUp | pentru a derula în sus |
Alte scurtături utile:
Scurtătură | Descriere |
---|---|
Ctrl+Shift+c | copiere text din terminal |
Ctrl+Shift+v | lipire text în terminal |
Shift+Insert | lipire text în terminal |
Paginile de manual sunt adesea de mari dimensiuni și avem nevoie să le parcurgem rapid (să navigăm prin ele). Pentru aceasta, după ce deschidem pagina de manual a unei comenzi, putem folosi combinațiile de taste de mai jos pentru a naviga în pagină:
Tastă | Scurtă descriere |
---|---|
/string_to_search | / (adică tasta slash) e folosită pentru a căuta string_to_search în pagina de manual |
n (next) | pentru a merge la următoarea apariție a cuvântului căutat cu / |
N (Shift + n) | pentru a merge la precedenta apariție a cuvântului |
q (quit) | pentru a închide pagina de manual |
Enter | pentru a derula în jos o linie |
f (forward) sau Space | pentru a derula în jos un ecran |
b (backward) | pentru a derula în sus un ecran |
d (down) | pentru a derula în jos jumătate de ecran |
u (up) | pentru a derula în sus jumătate de ecran |
Pe parcursul laboratoarelor, pentru descărcarea fișierelor necesare laboratorului, vom folosi Git. Git este un sistem de controlul versiunii și e folosit pentru versionarea codului în proiectele software mari. Celor interesați să aprofundeze conceptele din spatele comenzii git
, precum și utilizări avansate, le recomandăm cursul practic online de pe gitimmersion.
Informațiile despre laboratorul de USO se găsesc în acest repository Git.
Ctrl+Alt+t
. În listarea de mai jos student@uso:~$
este promptul unde introduceți comenzile, pe acela nu-l tastați.
student@uso:~$ cd ~ student@uso:~$ git clone https://github.com/systems-cs-pub-ro/uso-lab.git student@uso:~$ cd uso-lab/02-process/support/
Cam atât cu pregătirea laboratorului. Acum haideți să ne apucăm de treabă!
Ierarhia de procese în Linux este sub 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.
student@uso:~$ ps PID TTY TIME CMD 22101 pts/0 00:00:00 bash 22209 pts/0 00:00:00 ps
Tot cu ps
putem vizualiza un snapshot
al tuturor proceselor. Aceasta se poate obține folosind două variante ale comenzii:
student@uso:~$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.3 160140 7044 ? Ss 10:39 0:02 /sbin/init spla root 2 0.0 0.0 0 0 ? S 10:39 0:00 [kthreadd] [...] student 22101 0.0 0.2 31236 5192 pts/0 Ss 19:38 0:00 bash student 22114 0.0 0.2 31236 5008 pts/1 Ss+ 19:38 0:00 bash root 22151 0.0 0.3 25656 6260 ? S 19:40 0:00 /sbin/dhclient student 22191 0.0 0.1 46012 3656 pts/0 R+ 19:48 0:00 ps aux
Un utilitar echivalent lui Windows Task Manager pentru vizualizarea în timp real a proceselor care rulează, în linie de comandă, este htop.
student@uso:~$ htop
Procesul este identificat în sistem cu ajutorul unui număr numit PID (process ID). Acesta este unic în sistem. Atunci când un proces este creat, se asignează un PID nou, următorul crescător liber.
Un alt atribut important este PID-ul procesului părinte, PPID. Având o structură ierarhică, toate procesele au un părinte, părintele tuturor fiind init sau systemd (în funcție de sistem) și are PID-ul 1.
Atributul COMMAND ne spune numele procesului sau comanda cu care a fost creat:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND student 23176 0.0 0.1 46012 3644 pts/0 R+ 22:06 0:00 ps aux
Pentru o listă completă de atribute, verificați manualul.
Există mai multe stări în care un proces se poate afla:
Apăsând o combinație de taste din cele de mai sus, trimitem un semnal procesului:
Taste | Semnificație |
---|---|
Ctrl+C | trimite SIGINT |
Ctrl+Z | trimite SIGSTOP |
Ctrl+\ | trimite SIGQUIT |
În secțiunea Demo exemplificăm cum se trece prin aceste stări.
Un utilizator poate trimite un semnal unui proces folosind comanda kill! Este foarte important să înțelegem că scopul principal al utilitarului nu este omorârea de procese, deși poate face și asta. O listă a tuturor semnalelor posibile ce pot fi trimise aflăm prin
student@uso:~$ kill -l
Utilitarele pkill și killall termină procesele folosind ca argument numele procesului și nu PID-ul (ca la kill).
Redirectare stdout (standard output, în general mesaje afișate prin comenzi similare cu printf din C). Pentru a redirecta lista proceselor într-un fișier, folosim următoarea comandă:
student@uso:~$ ps aux > procese.txt
Astfel, am specificat procesului să nu mai afișeze rezultatul pe ecran, ci într-un fișier. Diferența între > și » este că primul înlocuiește conținutul fișierului procese.txt, pe când al2lea adaugă la sfârșitul fișierului.
Operatorul < folosit comanda < fisier.txt
setează comenzii intrarea fisier.txt
.
student@uso:~$ grep "Disable" < vm-actions-log.txt * Disable terminal bell and scrolling in terminal: * Disable cursor blinking in terminal: * Disable DNS usage in SSH server: * Disable automated screen locking:
Operatorul | este foarte important și uzual folosit. Acesta ia rezultatul primei comenzi și îl oferă ca intrare la a2a comandă. Câteva exemple:
student@uso:~$ ps aux | grep sleep student 22406 0.0 0.0 16116 828 pts/0 S 20:28 0:00 sleep 1000 student 22408 0.0 0.0 23076 1084 pts/0 S+ 20:28 0:00 grep --color=auto sleep
student@uso:~$ tree | grep Documents ├── Documents
Se pot înlănțui 2 sau mai multe comenzi.
Procesele daemon sunt procese ce rulează în fundal. De obicei, acestea sunt servicii ce servesc anumite funcții specifice. Acestea pot fi recunoscute ca având procesul părinte cu PID 1 (procesul init sau systemd).
Folosind ps
fără nici un parametru vizualizăm procesele din shell-ul curent asociate utilizatorului curent.
student@uso:~$ ps PID TTY TIME CMD 22101 pts/0 00:00:00 bash 22209 pts/0 00:00:00 ps
Tot cu ps
putem vizualiza un snapshot
al tuturor proceselor. Aceasta se poate obține folosind două variante ale comenzii:
student@uso:~$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.3 160140 7044 ? Ss 10:39 0:02 /sbin/init spla root 2 0.0 0.0 0 0 ? S 10:39 0:00 [kthreadd] [...] student 22101 0.0 0.2 31236 5192 pts/0 Ss 19:38 0:00 bash student 22114 0.0 0.2 31236 5008 pts/1 Ss+ 19:38 0:00 bash root 22151 0.0 0.3 25656 6260 ? S 19:40 0:00 /sbin/dhclient student 22191 0.0 0.1 46012 3656 pts/0 R+ 19:48 0:00 ps aux
Un utilitar echivalent lui Windows Task Manager pentru vizualizarea în timp real a proceselor care rulează, în linie de comandă, este htop.
student@uso:~$ htop
În mod implicit, când afișăm procesele, ni se arată următoarele atribute:
student@uso:~$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND [...]
Putem specifica ce atribute să ne afișeze și în ce ordine dorim:
student@uso:~$ ps -ax -o ppid,pid,cmd PPID PID CMD 0 1 /sbin/init splash 0 2 [kthreadd] [...]
Pentru a selecta doar procesele pornite de utilizatorul student:
student@uso:~$ ps -f -u student UID PID PPID C STIME TTY TIME CMD student 900 1 0 11:10 ? 00:00:00 /lib/systemd/systemd --user student 901 900 0 11:10 ? 00:00:00 (sd-pam) [...]
Vom folosi ca exemplu utilitarul sleep
. Trebuie să știm dacă procesul nostru rulează sau nu. Pentru a verifica acest lucru, dintr-un alt terminal, ne folosim de utilitarul ps
:
Terminal 1:
student@uso:~$ sleep 100
Terminal 2:
student@uso:~$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.3 160140 7044 ? Ss 10:39 0:02 /sbin/init spla root 2 0.0 0.0 0 0 ? S 10:39 0:00 [kthreadd] [...] student 22268 0.0 0.0 16116 884 pts/0 S 19:54 0:00 sleep 100 student 22281 0.0 0.1 46012 3744 pts/0 R+ 19:54 0:00 ps aux
Am găsit procesul sleep
în sistem. Putem folosi utilitarul pgrep
pentru a afla PID-ul procesului.
student@uso:~$ pgrep sleep 22268
Pentru a opri procesul, vom folosi combinația de taste Ctrl+Z:
student@uso:~$ sleep 100 student@uso:~$ ^Z [1]+ Stopped sleep 100 student@uso:~$ jobs [1]+ Stopped sleep 100
Am folosit utilitarul jobs
pentru a vedea ce procese sunt active în terminalul curent. De aici putem folosi bg (background) pentru a porni procesul în mod interactiv sau fg (foreground) pentru a porni procesul în mod neinteractiv. Mai simplu, la bg
putem da alte comenzi în timp ce programul nostru rulează, iar la fg
nu putem să dăm alte comenzi.
Vom folosi în continuare comanda kill pentru a trimite semnale proceselor. Această comandă nu omoară neapărat procesul, în ciuda numelui.
student@uso:~$ kill --help kill: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec] Send a signal to a job.
Dintr-un alt terminal aflăm PID-ul procesului sleep
folosind utilitarul pgrep.
Pentru a termina procesul, trimitem semnalul 9 (SIGKILL):
student@uso:~$ jobs [1]+ Stopped sleep 100 student@uso:~$ pgrep sleep 22286 student@uso:~$ kill -9 22286 student@uso:~$ jobs [1]+ Killed sleep 100
Am transmis semnalul 9 (SIGKILL) procesului 22286, iar acesta a fost terminat instant.
Pentru a redirecta lista proceselor într-un fișier, folosim următoarea comandă:
student@uso:~$ ps aux > procese.txt
Astfel, am specificat procesului să nu mai afișeze rezultatul pe ecran, ci într-un fișier. Diferența între > și » este că primul înlocuiește conținutul fișierului procese.txt, pe când al2lea adaugă la sfârșitul fișierului. Astfel, executând a2a oară comanda:
student@uso:~$ ps aux >> procese.txt
Vom avea în fișierul procese.txt
afișat de 2 ori ieșirea comenzii.
Operatorul | este foarte important și uzual folosit. Acesta ia rezultatul primei comenzi și îl oferă ca intrare la a doua comandă. Câteva exemple:
student@uso:~$ ps aux | grep sleep student 22406 0.0 0.0 16116 828 pts/0 S 20:28 0:00 sleep 1000 student 22408 0.0 0.0 23076 1084 pts/0 S+ 20:28 0:00 grep --color=auto sleep
student@uso:~$ tree | grep Documents ├── Documents
Folosind ps
fără nici un parametru vizualizăm procesele din shell-ul curent asociate utilizatorului curent.
student@uso:~$ ps PID TTY TIME CMD 22101 pts/0 00:00:00 bash 22209 pts/0 00:00:00 ps
Parametrul aux asociat lui ps ne arată toate procesele din sistem:
student@uso:~$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.3 160140 7044 ? Ss 10:39 0:02 /sbin/init spla root 2 0.0 0.0 0 0 ? S 10:39 0:00 [kthreadd] [...] student 22101 0.0 0.2 31236 5192 pts/0 Ss 19:38 0:00 bash student 22114 0.0 0.2 31236 5008 pts/1 Ss+ 19:38 0:00 bash root 22151 0.0 0.3 25656 6260 ? S 19:40 0:00 /sbin/dhclient student 22191 0.0 0.1 46012 3656 pts/0 R+ 19:48 0:00 ps aux
Pentru a selecta doar procesele pornite de utilizatorul student folosim -u:
student@uso:~$ ps -f -u student UID PID PPID C STIME TTY TIME CMD student 900 1 0 11:10 ? 00:00:00 /lib/systemd/systemd --user student 901 900 0 11:10 ? 00:00:00 (sd-pam) [...]
Putem specifica ce atribute să ne afișeze și în ce ordine dorim:
student@uso:~$ ps -ax -o ppid,pid,cmd PPID PID CMD 0 1 /sbin/init splash 0 2 [kthreadd] [...]
Până a trece mai departe, trebuie să vă asigurați că ați înțeles cum trebuie navigarea printr-o ierarhie de procese. Pentru asta, parcurgeți următoarele exerciții după care verificați cu asistentul că totul este în regulă.
Vom folosi ca exemplu programul bg-proc.sh. Acesta afișează în fiecare secundă câte un mesaj “Tick” sau “Tock”. Pornim programul:
student@uso:~/.../02-process/support$ ./bg-proc.sh Tick! Tock! Tick! ^C
L-am terminat cu Ctrl+C:
Îl pornim din nou și de data asta îl oprim cu Ctrl+Z. Ce observăm?
student@uso:~/.../02-process/support$ ./bg-proc.sh Tick! Tock! Tick! ^Z [1]+ Stopped ./bg-proc.sh
Verficăm dacă procesul încă există în sistem:
student@uso~/.../02-process/support$ ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.3 160140 7152 ? Ss oct08 0:03 /sbin/init splash root 2 0.0 0.0 0 0 ? S oct08 0:00 [kthreadd] [...] **student 23597 0.0 0.1 21532 3532 pts/0 T 09:53 0:00 /bin/bash ./bg-proc.sh** student 23600 0.0 0.0 16116 780 pts/0 T 09:53 0:00 sleep 1 student 23601 0.0 0.1 46012 3784 pts/0 R+ 09:53 0:00 ps aux
Pentru a reporni procesul avem 2 variante:
student@uso:~/.../02-process/support$ ./bg-proc.sh Tick! Tock! [1]+ Stopped ./bg-proc.sh student@uso:~/.../02-process/support$ bg [1]+ ./bg-proc.sh & student@uso:~/.../02-process/support$ Tick! Tock! lsTick! batman.sh bg-proc.sh it-s-a-trap.sh student@uso:~/.../02-process/support$ Tock! Tick! Tock! ^C student@uso:~/.../02-process/support$ Tick! Tock!
Puteți observa că am încercat să termin programul folosind Ctrl+C. Acest lucru nu a fost posibil pentru că acesta rula în fundal. Pentru asta trebuie să aducem procesul în prim-plan și să îl terminăm sau să îi aflăm PID-ul și să-l terminăm folosind utilitarul kill.
Exerciții
foreground
și apoi în background.Pentru a redirecta lista proceselor într-un fișier, folosim următoarea comandă:
student@uso:~$ ps aux > procese.txt
Un alt exemplu de redirectare este:
student@uso:~/.../02-process/support$ echo "prima linie din fisier" > fis.txt student@uso:~/.../02-process/support$ cat fis.txt prima linie din fisier student@uso:~/.../02-process/support$ echo "a2a linie din fisier" >> fis.txt student@uso:~/.../02-process/support$ cat fis.txt prima linie din fisier a2a linie din fisier student@uso:~/.../02-process/support$ echo "a3a linie din fisier" > fis.txt student@uso:~/.../02-process/support$ cat fis.txt a3a linie din fisier
Putem observa că la a3a linie am folosit > în loc de » și am șters conținutul anterior al fișierului.
Putem căuta după un anumit proces din sistem astfel:
student@uso:~$ ps aux | grep sleep student 22406 0.0 0.0 16116 828 pts/0 S 20:28 0:00 sleep 1000 student 22408 0.0 0.0 23076 1084 pts/0 S+ 20:28 0:00 grep --color=auto sleep
Care este logica din spatele comenzii? În loc să ne afișeze nouă pe ecran rezultatul comenzii ps aux, acesta a fost transmis către următoarea comandă grep. Comanda din urmă a căutat cuvântul sleep
în rezultatul comenzi ps aux
.
Exerciții
Pentru această secțiune trebuie să vă asigurați că sunteți în directorul potrivit. Rulați comanda
cd ~/uso-lab/02-process/support/
Putem verifica dacă comanda executată anterior s-a executat cu succes folosind $?:
student@uso:~/.../02-process/support$ cat README.md uso === * Directorul ''lab02'' conține toate fișierele și structura de directoare necesare rezolvării laboratorului 2 de către studenți student@uso:~/.../02-process/support$ echo $? 0 student@uso:~/.../02-process/support$ cat fisier-care-nu-exista.txt cat: fisier-care-nu-exista.txt: No such file or directory student@uso:~/.../02-process/support$ echo $? 1
Atunci când valoarea este 0, procesul s-a executat cu succes. Orice diferit de 0 este o eroare.
Exerciții
Afișăm toate procesele din sistem cu atributele PID, PPID, CMD:
student@uso:~/.../02-process/support$ ps ax -o pid,ppid,cmd PID PPID CMD 1 0 /sbin/init splash [...] 19540 2 [jfsSync] 22046 2 [kworker/0:1] 22090 900 /usr/lib/gnome-terminal/gnome-terminal-server 22101 22090 bash 22114 22090 bash 22234 1 /usr/bin/python3 /usr/bin/update-manager --no-update --no-focus-on-map 22559 1 /usr/sbin/cupsd -l 22560 1 /usr/sbin/cups-browsed 22742 2 [loop10] 22785 1 /usr/lib/snapd/snapd 22913 2 [loop12] 23200 2 [kworker/u2:0] 23394 530 /sbin/dhclient -d -q -sf /usr/lib/NetworkManager/nm-dhcp-helper -pf /run/dhclient-enp0s8.pid -lf /var/lib/NetworkManager/dhclient-fda81623-2338-36f 23519 2 [kworker/u2:1] 23974 2 [kworker/u2:2] 24107 22101 ps ax -o pid,ppid,cmd
Putem observa că părintele comenzii executate de noi este bash; are PID-ul 22101.
Exerciții
Pentru acest exercițiu trebuie să vă asigurați că sunteți în directorul potrivit. Rulați comanda
cd ~/uso-lab/02-process/support/
În directorul respectiv este scriptul batman.sh
:
student@uso:~/.../02-process/support$ ls batman.sh bg-proc.sh it-s-a-trap.sh
Rulați scriptul batman.sh
. 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:
|
|
2.1 Î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
.
Descărcați un fișier video de pe Internet. Puteți instala și utiliza youtube-dl pentru a descărca un film de pe YouTube.
Rulați filmul cu un player de filme. În timp ce rulează, ștergeți fișierul.
Până la a termina de rulat filmul, recuperați fișierul folosind procfs (din /proc
), din directorul aferent procesului player de filme.
Folosind utilitarul strace
inspectați ce fișiere din procfs (din /proc
) sunt deschide de utilitarul lsof
pentru afișarea descriptorilor deschiși de un proces existent, de utilitarul pmap
pentru afișarea memorie unui proces și de utilitarul free
pentru afișarea memoriei disponibile din sistem.