This shows you the differences between two versions of the page.
systems:uso:laboratoare:laborator-05 [2012/09/24 02:14] george.milescu [9. Semnale] |
— (current) | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Laborator 05 - Procese, semnale, pipe-uri ====== | ||
- | ===== Tutorial ===== | ||
- | |||
- | ===== 1. ps ===== | ||
- | |||
- | <hidden> | ||
- | * noțiunea de proces | ||
- | * **neapărat** deosebirea între proces și executabil (se face și la curs dar merită insistat) | ||
- | </hidden> | ||
- | |||
- | **a)** Tastați comanda și observați cu atenție textul apărut în terminal ca urmare a rulării acesteia: | ||
- | <code>ps</code> | ||
- | La ce se referă liniile apărute? **R:** Se afișează procesele deschise din terminalul curent. Apar doar două procese: shell-ul ''bash'' și procesul ''ps'': | ||
- | <code> | ||
- | student@uso:~$ ps | ||
- | PID TTY TIME CMD | ||
- | 3821 pts/1 00:00:00 bash | ||
- | 3877 pts/1 00:00:00 ps | ||
- | </code> | ||
- | |||
- | **b)** Adăugați argumentele ''-ef'' comenzii anterioare. | ||
- | <code>ps -ef</code> | ||
- | Se vor afișa toate procesele ce rulează în sistem: | ||
- | <code> | ||
- | student@uso:~$ ps -ef | ||
- | UID PID PPID C STIME TTY TIME CMD | ||
- | root 1 0 0 19:37 ? 00:00:00 /sbin/init | ||
- | root 2 0 0 19:37 ? 00:00:00 [kthreadd] | ||
- | root 3 2 0 19:37 ? 00:00:00 [ksoftirqd/0] | ||
- | root 6 2 0 19:37 ? 00:00:00 [migration/0] | ||
- | root 7 2 0 19:37 ? 00:00:00 [watchdog/0] | ||
- | root 8 2 0 19:37 ? 00:00:00 [migration/1] | ||
- | root 10 2 0 19:37 ? 00:00:00 [ksoftirqd/1] | ||
- | root 12 2 0 19:37 ? 00:00:00 [watchdog/1] | ||
- | root 13 2 0 19:37 ? 00:00:00 [cpuset] | ||
- | root 14 2 0 19:37 ? 00:00:00 [khelper] | ||
- | root 15 2 0 19:37 ? 00:00:00 [kdevtmpfs] | ||
- | root 16 2 0 19:37 ? 00:00:00 [netns] | ||
- | root 18 2 0 19:37 ? 00:00:00 [sync_supers] | ||
- | [...] | ||
- | </code> | ||
- | **c)** Folosiți ''man ps'' pentru a găsi descrierea celor două argumente de mai sus. Folosiți opțiunea de cautare din man (''/-e'') pentru a ajunge mai rapid la descrierea dorită: | ||
- | <code> | ||
- | -e Select all processes. Identical to -A. | ||
- | -f Do full-format listing. | ||
- | </code> | ||
- | |||
- | **d)** În output-ul comenzii de mai sus, ce reprezintă câmpurile afișate? Folosiți ''man ps'' împreună cu opțiunea de căutare pentru a găsi descrierea câmpurilor afișate. | ||
- | <code> | ||
- | uid UID see euid. (alias euid). | ||
- | euid EUID effective user ID (alias uid). | ||
- | pid PID process ID number of the process. | ||
- | ppid PPID parent process ID. | ||
- | c C processor utilization. Currently, this is the integer value of the percent usage over the lifetime of the process. | ||
- | start_time START starting time or date of the process. | ||
- | tname TTY controlling tty (terminal). | ||
- | time TIME cumulative CPU time, "[DD-]HH:MM:SS" format. | ||
- | ucmd CMD see comm. | ||
- | comm COMMAND command name (only the executable name). | ||
- | </code> | ||
- | |||
- | **e)** Informații detaliate despre procesele care ruleaza în sistem pot afișate și folosind argumentele ''aux''. În acest caz argumentele comenzii ''ps'' nu sunt prefixate de caracterul ''-''. Este cazul argumentelor date în format BSD. | ||
- | <code> | ||
- | student@uso:~$ ps aux | ||
- | USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND | ||
- | root 1 0.0 0.0 24456 2416 ? Ss 19:37 0:00 /sbin/init | ||
- | root 2 0.0 0.0 0 0 ? S 19:37 0:00 [kthreadd] | ||
- | root 3 0.0 0.0 0 0 ? S 19:37 0:00 [ksoftirqd/0] | ||
- | root 6 0.0 0.0 0 0 ? S 19:37 0:00 [migration/0] | ||
- | root 7 0.0 0.0 0 0 ? S 19:37 0:00 [watchdog/0] | ||
- | root 8 0.0 0.0 0 0 ? S 19:37 0:00 [migration/1] | ||
- | root 10 0.0 0.0 0 0 ? S 19:37 0:00 [ksoftirqd/1] | ||
- | root 12 0.0 0.0 0 0 ? S 19:37 0:00 [watchdog/1] | ||
- | root 13 0.0 0.0 0 0 ? S< 19:37 0:00 [cpuset] | ||
- | root 14 0.0 0.0 0 0 ? S< 19:37 0:00 [khelper] | ||
- | root 15 0.0 0.0 0 0 ? S 19:37 0:00 [kdevtmpfs] | ||
- | root 16 0.0 0.0 0 0 ? S< 19:37 0:00 [netns] | ||
- | root 18 0.0 0.0 0 0 ? S 19:37 0:00 [sync_supers] | ||
- | root 19 0.0 0.0 0 0 ? S 19:37 0:00 [bdi-default] | ||
- | root 20 0.0 0.0 0 0 ? S< 19:37 0:00 [kintegrityd] | ||
- | root 21 0.0 0.0 0 0 ? S< 19:37 0:00 [kblockd] | ||
- | root 22 0.0 0.0 0 0 ? S< 19:37 0:00 [ata_sff] | ||
- | </code> | ||
- | |||
- | <hidden>Pentru grupele below average le spuneți că există și formatul BSD dar că nu trebuie să se chinuie să-l rețină. Pentru grupele above average le spuneți că uneori formatul BSD oferă mai multe informații, totul depinde de ce vrei să faci cu ele.</hidden> | ||
- | |||
- | Există 3 formate pentru opțiunile unei comenzi: | ||
- | * formatul lung (de exemplu ''--help'') | ||
- | * formatul GNU (ca în ''ls -l'') | ||
- | * formatul BSD (''ps aux'') | ||
- | |||
- | **f)** Puteți vedea semnificația argumentelor mai des folosite pentru ''ps'', în toate cele 3 formate, rulând <code>ps --help</code> sau o comandă cu un argument nevalid. | ||
- | <code> | ||
- | student@uso:~$ ps --help | ||
- | ********* simple selection ********* ********* selection by list ********* | ||
- | -A all processes -C by command name | ||
- | -N negate selection -G by real group ID (supports names) | ||
- | -a all w/ tty except session leaders -U by real user ID (supports names) | ||
- | -d all except session leaders -g by session OR by effective group name | ||
- | -e all processes -p by process ID | ||
- | T all processes on this terminal -s processes in the sessions given | ||
- | a all w/ tty, including other users -t by tty | ||
- | g OBSOLETE -- DO NOT USE -u by effective user ID (supports names) | ||
- | r only running processes U processes for specified users | ||
- | x processes w/o controlling ttys t by tty | ||
- | *********** output format ********** *********** long options *********** | ||
- | -o,o user-defined -f full --Group --User --pid --cols --ppid | ||
- | -j,j job control s signal --group --user --sid --rows --info | ||
- | -O,O preloaded -o v virtual memory --cumulative --format --deselect | ||
- | -l,l long u user-oriented --sort --tty --forest --version | ||
- | -F extra full X registers --heading --no-heading --context | ||
- | ********* misc options ********* | ||
- | -V,V show version L list format codes f ASCII art forest | ||
- | -m,m,-L,-T,H threads S children in sum -y change -l format | ||
- | -M,Z security data c true command name -c scheduling class | ||
- | -w,w wide output n numeric WCHAN,UID -H process hierarchy | ||
- | </code> | ||
- | |||
- | **g)** Informațiile oferite de utilitarul ''ps'' se pot filtra specificând un set de argumente. Spre exemplu, pentru a afișa doar procesele deținute de utilizatorul ''student'', rulați comanda | ||
- | <code> | ||
- | student@uso:~$ ps -u student | ||
- | PID TTY TIME CMD | ||
- | 2038 ? 00:00:00 x-session-manag | ||
- | 2086 ? 00:00:00 ssh-agent | ||
- | 2089 ? 00:00:00 dbus-launch | ||
- | 2090 ? 00:00:01 dbus-daemon | ||
- | 2154 ? 00:00:00 start_kdeinit | ||
- | 2155 ? 00:00:00 kdeinit4 | ||
- | 2156 ? 00:00:00 klauncher | ||
- | 2158 ? 00:00:04 kded4 | ||
- | 2163 ? 00:00:00 bluedevil-helpe | ||
- | 2165 ? 00:00:00 obex-data-serve | ||
- | 2337 ? 00:00:00 bluedevil-monol | ||
- | 2339 ? 00:00:00 kglobalaccel | ||
- | </code> | ||
- | Alternativ puteți rula și | ||
- | <code> | ||
- | student@uso:~$ ps U student | ||
- | PID TTY STAT TIME COMMAND | ||
- | 2038 ? Ss 0:00 /bin/sh /usr/bin/x-session-manager | ||
- | 2086 ? Ss 0:00 /usr/bin/ssh-agent /usr/bin/dbus-launch --exit-with-session x-session-manager | ||
- | 2089 ? S 0:00 /usr/bin/dbus-launch --exit-with-session x-session-manager | ||
- | 2090 ? Ss 0:01 //bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session | ||
- | 2154 ? S 0:00 /usr/lib/kde4/libexec/start_kdeinit +kcminit_startup | ||
- | 2155 ? Ss 0:00 kdeinit4: kdeinit4 Running... | ||
- | 2156 ? S 0:00 kdeinit4: klauncher [kdeinit] --fd=9 | ||
- | 2158 ? Sl 0:04 kdeinit4: kded4 [kdeinit] | ||
- | 2163 ? S 0:00 /usr/bin/bluedevil-helper | ||
- | 2165 ? S 0:00 /usr/bin/obex-data-server --no-daemon | ||
- | 2337 ? S 0:00 /usr/bin/bluedevil-monolithic | ||
- | 2339 ? S 0:00 /usr/bin/kglobalaccel | ||
- | 2341 ? Sl 0:00 /usr/bin/kwalletd | ||
- | 2344 ? S 0:00 /usr/bin/kactivitymanagerd | ||
- | </code> | ||
- | |||
- | <note tip> **Se recomandă** folosirea argumentelor cu ''-'' (în stil GNU). Cu toate acestea, în unele cazuri forma BSD este mai potrivită.</note> | ||
- | |||
- | ===== 2. top ===== | ||
- | |||
- | **a)** Utilitarul ''ps'' poate fi folosit pentru a "face o poză" proceselor sistemului la un anumit moment de timp. Pentru a vizualiza informații în timp real, folosim ''top''. Rulați comanda | ||
- | <code>top</code> | ||
- | |||
- | Se vor afișa primele procese sortate după gradul de folosire al procesorului. | ||
- | |||
- | **b)** Parametrii acestei comenzi sunt similari comenzii ''ps''. Folosiți ''top'' pentru a lista doar procesele utilizatorului ''student'': <code>top -u student</code> | ||
- | |||
- | **c)** Dacă tastați ''h'' în timp ce ''top'' rulează, se afișează un ecran informativ in care sunt listate comenzile interactive acceptate de ''top''. De exemplu, dacă tastați ''u'' puteți selecta interactiv ce utilizatori să fie afișați. | ||
- | |||
- | Porniți o instanță nouă de ''top'' și afișați procesele utilizatorului ''root''. | ||
- | |||
- | ===== 3. Ierarhia de procese ===== | ||
- | |||
- | <hidden>De ce avem nevoie să vedem ierarhia de procese?</hidden> | ||
- | |||
- | **a)** Utilitarul ''pstree'' afișează sub formă arborescentă toate procesele existente în momentul lansării lui. Utilizând <code>pstree</code> identificați primul proces creat la lansarea sistemului de operare (rădăcina arborelui). | ||
- | |||
- | **b)** Identificați PID-ul acestui proces folosind ''ps''. Folosiți argumentul ''-C'' pentru a specifica numele executabilului ''init''. | ||
- | |||
- | |||
- | ===== 4. Timpul de execuție ===== | ||
- | |||
- | **a)** Pentru a afla cât timp a rulat un anumit proces, se poate folosi comanda ''time''. Rulați <code>time sleep 3</code> | ||
- | |||
- | |||
- | **b)** Output-ul comenzii ''time'' conține trei valori de timp: ''real'', ''user'', ''sys''. Folosiți pagina de man pentru a afla ce reprezinta fiecare valoare. | ||
- | <code> | ||
- | To run the command `ls -Fs' and show just the user, system, and total time: | ||
- | time -f "%E real,%U user,%S sys" ls -Fs | ||
- | [...] | ||
- | E Elapsed real (wall clock) time used by the process, in [hours:]minutes:seconds. | ||
- | U Total number of CPU-seconds that the process used directly (in user mode), in seconds. | ||
- | S Total number of CPU-seconds used by the system on behalf of the process (in kernel mode), in seconds. | ||
- | </code> | ||
- | |||
- | ===== 5. Sistemul de fișiere procfs ===== | ||
- | |||
- | <hidden> | ||
- | * Sisteme de fișiere virtuale, puțin listing al lor. | ||
- | * Ce conține ''/proc''. | ||
- | </hidden> | ||
- | |||
- | **a)** Rulați comanda <code>vim beatles</code> Scrieți "we all live in a yellow submarine" în fisier și salvați fișierul. Nu iesiți din ''vim''. | ||
- | |||
- | **b)** Într-un alt terminal, folosiți ''ps'' pentru a identifica PID-ul procesului ''vim'' pornit. Folosiți argumentul ''-C'' al utilitarului ''ps''. | ||
- | |||
- | **c)** Rulați comanda ''cd /proc/$PID'' (înlocuiți ''$PID'' cu PID-ul găsit anterior). Listați conținutul directorului în care vă aflați. | ||
- | |||
- | * Link-ul ''exe'' pointează către executabilul ce a creat procesul. Care este acesta pentru cazul nostru? | ||
- | * Fișierul ''cmdline'' conține linia de comandă folsoită pentru lansarea în execuție a procesului. Verificați conținutul fișierului folosind ''cat''. | ||
- | * Folderul ''fd'' conține legături simbolice către descriptorii de fișier folosiți de proces. Primii 3 descriptori sunt cei standard (0: stdin, 1: stdout, 2: stderr). | ||
- | |||
- | **d)** Închideți sesiunea de vim deschisă anterior. Reveniți în terminalul în care ați vizualizat structura lui ''procfs''. Listați conținutul directorului. Ce observați? | ||
- | |||
- | |||
- | ===== 6. uptime ===== | ||
- | |||
- | **a)** Rulați comanda ''uptime''. Folosind pagina de man a utilitarului, identificați ce reprezintă cele trei numere de la ''load average''. | ||
- | <code> | ||
- | student@uso:~$ man uptime | ||
- | [...] | ||
- | uptime gives a one line display of the following information. The current time, how long the system has been running, how many users are currently logged on, and the system load averages for the past 1, 5, and 15 minutes. | ||
- | </code> | ||
- | |||
- | **b)** Rulați executabilul [[http://elf.cs.pub.ro/uso/store/uptime_ex | uptime_ex]] (execuția acestuia dureză câteva secunde). În timp de executabilul ''uptime_ex'' rulează, executați într-un terminal separat comanda ''uptime'' de câteva ori la rând. | ||
- | |||
- | Cum variază valorile numerice de load? Ce credeți că face programul? | ||
- | |||
- | |||
- | ===== 7. Pipe-uri anonime ===== | ||
- | |||
- | **a)** Construiți, în directorul ''~'' creați un director numit ''1960s'', și în el creați fișierele următoare: | ||
- | <code> | ||
- | touch Ticket-to-Ride_TheBeatles.txt Yesterday_TheBeatles.txt Penny-Lane_TheBeatles.txt | ||
- | touch Satisfaction_RollingStones Brown-Sugar_RollingStones Wild-Horses_RollingStones Play-With-Fire_RollingStones | ||
- | touch Hey-Jude_TheBeatles | ||
- | touch Rainy-Day-Women_BobDylan | ||
- | </code> | ||
- | |||
- | **b)** Ne interesează drepturile fișierelor ce conțin ''TheBeatles'' în nume. Tastați comenzile următoare: | ||
- | |||
- | <hidden> | ||
- | * despre redirectări (pe scurt, doar cât să le folosească) | ||
- | </hidden> | ||
- | |||
- | <code> | ||
- | student@uso:~$ cd ~/1960s | ||
- | student@uso:~/1960s$ ls -l > temp_file | ||
- | student@uso:~/1960s$ cat temp_file | ||
- | student@uso:~/1960s$ grep TheBeatles temp_file | ||
- | student@uso:~/1960s$ rm temp_file | ||
- | </code> | ||
- | |||
- | <note tip>Comanda ''grep'' citește fișierul primit ca parametru și afișează doar liniile ce se potrivesc cu un anumit șablon. Mai multe detalii într-un laborator ulterior.</note> | ||
- | |||
- | Observați că am folosit un fișier suplimentar (''temp_file'') în care am stocat rezultatele intermediare. | ||
- | |||
- | **c)** Tastați comanda <code>student@uso:~/1960s$ ls -l | grep greek</code> | ||
- | |||
- | De această dată, s-a folosit o comandă compusă. | ||
- | |||
- | Caracterul ''|'' (pipe) este folosit pentru a înlănțui 2 comenzi, legând ieșirea standard a primei comenzi la intrarea standard a celeilalte, așa cum arată și figura următoare: | ||
- | |||
- | {{http://elf.cs.pub.ro/uso/store/04_pipe.png}} | ||
- | |||
- | Folosind ''>'' și ''<'' putem face ca o comandă să scrie într-un fișier sau să citească dintr-un fișier. Folosind ''|'' fișierul nu mai este necesar. | ||
- | |||
- | Rulați comanda <code>student@uso:~/1960s$ ls -l | cat | cat | cat | cat | cat | cat</code> | ||
- | |||
- | Câte fișiere ar fi fost necesare dacă nu foloseam pipe-uri? | ||
- | |||
- | ===== 8. Finalinzarea execuției unui proces ===== | ||
- | |||
- | **a)** Un proces își poate termina cu succes (status 0) sau cu eroare (status diferit de 0). Într-un terminal statusul cu care s-a încheiat ultimul proces lansat se poate vedea cu ajutorul comenzii <code>echo $?</code> | ||
- | |||
- | **b)** **true** și **false** sunt două programe care întotdeauna se termină cu succes, respectiv cu eroare: | ||
- | <code> | ||
- | student@uso:~$ true | ||
- | student@uso:~$ echo $? | ||
- | 0 | ||
- | student@uso:~$ false | ||
- | student@uso:~$ echo $? | ||
- | 1 | ||
- | </code> | ||
- | |||
- | **c)** Folosind operatorii **&&** și **||**, putem rula un al doilea proces doar dacă primul proces s-a încheiat cu succes, respectiv eroare. Operatorii se aseamănă cu funțiile logile AND și OR. | ||
- | |||
- | Testați următoarele comenzi și observați dacă se execută sau nu procesul echo: | ||
- | <code> | ||
- | student@uso:~$ true && echo "Success" | ||
- | student@uso:~$ false && echo "Success" | ||
- | student@uso:~$ true || echo "Fail" | ||
- | student@uso:~$ false || echo "Fail" | ||
- | </code> | ||
- | |||
- | |||
- | ===== 9. Semnale ===== | ||
- | |||
- | <hidden> | ||
- | * De ce comunicăm între/cu procese? //Pe scurt// | ||
- | * semnale, tipuri de semnale. Nu multe detalii | ||
- | </hidden> | ||
- | |||
- | **a)** Unul din mecanismele prin care se poate comunica între procese sunt semnalele. Un utilizator poate trimite un semnal unui proces folosind comanda ''kill''. | ||
- | |||
- | Utilizați ''kill -l'' pentru a vedea toate semnalele care se pot trimite unui proces. | ||
- | <code> | ||
- | student@uso~$ 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 | ||
- | 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 | ||
- | 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 | ||
- | 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 | ||
- | 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 | ||
- | 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 | ||
- | 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 | ||
- | 63) SIGRTMAX-1 64) SIGRTMAX | ||
- | </code> | ||
- | |||
- | **b)** Descărcați programul [[http://elf.cs.pub.ro/uso/store/signal_test | signal_test]], faceți-l executabil și rulați-l: | ||
- | <code> | ||
- | student@uso~$ chmod +x signal_test | ||
- | student@uso~$ ./signal_test | ||
- | </code> | ||
- | |||
- | **c)** Deschideți un alt terminal și rulați comanda următoare pentru a afla PID-ul procesului creat anterior <code>pidof signal_test</code> | ||
- | |||
- | <hidden> | ||
- | * Ce înseamnă formularea ''$(cmd)''. | ||
- | * Îi descurajăm să folosească ''`cmd`'' datorită asemănărilor prea mari cu '' 'cmd' '' | ||
- | * Să le ziceți pentru above average să consulte documentația pentru a vedea diferențe între ''pidof'' și ''pgrep''. | ||
- | </hidden> | ||
- | |||
- | Alternativ, puteți folosi comanda ''pgrep''. | ||
- | |||
- | Rulați următoarele comenzi din cel de-al doilea terminal pentru a trimite mesaje procesului creat: | ||
- | |||
- | <code> | ||
- | student@uso~$ kill -1 $(pidof signal_test) | ||
- | student@uso~$ kill -2 $(pidof signal_test) | ||
- | student@uso~$ kill -3 $(pidof signal_test) | ||
- | student@uso~$ kill -5 $(pidof signal_test) | ||
- | student@uso~$ kill -6 $(pidof signal_test) | ||
- | student@uso~$ kill -7 $(pidof signal_test) | ||
- | student@uso~$ kill -11 $(pidof signal_test) | ||
- | student@uso~$ kill -19 $(pidof signal_test) | ||
- | student@uso~$ kill -18 $(pidof signal_test) | ||
- | student@uso~$ kill -INT $(pidof signal_test) | ||
- | student@uso~$ kill $(pidof signal_test) | ||
- | student@uso~$ pkill signal_test | ||
- | student@uso~$ pkill -1 signal_test | ||
- | student@uso~$ pkill -INT signal_test | ||
- | </code> | ||
- | |||
- | **d)** În terminalul în care programul ''signal_test'' rulează, tastați, //pe rând// combinațiile de taste următoare și observați ce semnale se trimit: | ||
- | * ''CTRL-Z'' | ||
- | * ''CTRL-C'' | ||
- | * ''CTRL-\'' | ||
- | |||
- | La final, rulați comanda: | ||
- | <code> | ||
- | student@uso~$ kill -9 $(pidof signal_test) | ||
- | </code> | ||
- | |||
- | Observați că semnalul 9 (SIGKILL) nu poate fi tratat de nici o aplicație. | ||
- | |||
- | ===== 10. trap ===== | ||
- | |||
- | Comanda ''trap'' poate fi folosită pentru a executa o comandă în momentul în care shell-ul primește un anumit semnal. | ||
- | |||
- | Executați comanda: | ||
- | <code>trap "echo shell closed > /tmp/log.terminal" SIGHUP</code> | ||
- | |||
- | În momentul în care shell-ul primește semnalul HUP, va executa comanda ''echo''. | ||
- | |||
- | Verificați conținutul fișierului ''/tmp/log.terminal''. Observați că acest fișier nu există. | ||
- | |||
- | Ce reprezintă ''$$''? (dacă nu vă amintiți, căutați în laboratorul din săptămâna trecută) | ||
- | |||
- | Trimiteți semanul: | ||
- | <code>kill -HUP $$</code> | ||
- | |||
- | Verificați conținutul fișierului ''/tmp/log.terminal''. | ||
- | |||
- | Citiți mai multe în ''man bash''. | ||
- | |||
- | |||
- | |||
- | ===== 11. xkill ===== | ||
- | |||
- | Pentru a forța închiderea unei aplicații grafice se poate folosi comanda ''xkill''. | ||
- | |||
- | Deschideți un calculator. (Applications -> Accessories -> Calculator) | ||
- | |||
- | Deschideți un terminal. Tastați comanda ''xkill''. | ||
- | |||
- | În terminal a apărut mesajul: | ||
- | <code>Select the window whose client you wish to kill with button 1</code> | ||
- | Ce formă are mouse-ul? | ||
- | |||
- | Dați click pe ''Calculator''. | ||
- | |||
- | |||
- | |||
- | ===== 12. fg. Operatorul &. ===== | ||
- | |||
- | <hidden> | ||
- | background, foreground, diferențe între modurile de trimitere în background | ||
- | </hidden> | ||
- | |||
- | Utilizând ''vim'' deschideți fișierul ''Uranus'': | ||
- | |||
- | <code> | ||
- | vim Uranus | ||
- | </code> | ||
- | |||
- | Scrieți textul ''Uranus, Geea'' în fișier. | ||
- | |||
- | Tastați ''Ctrl-Z''. Procesul este trimis în background. | ||
- | |||
- | Rulând | ||
- | |||
- | <code> | ||
- | ps | ||
- | </code> | ||
- | |||
- | observați câte procese se afișează. | ||
- | |||
- | Procesul ''vim'' se află în background. Reveniți la el tastând comanda | ||
- | |||
- | <code> | ||
- | fg | ||
- | </code> | ||
- | |||
- | Trimiteți-l din nou în fundal (''Ctrl-Z''). Porniți un alt proces ''vim'', direct în fundal cu | ||
- | |||
- | <code> | ||
- | vim Cronos & | ||
- | </code> | ||
- | |||
- | Prezența lui ''&'' a forțat procesul să pornească direct în fundal. | ||
- | |||
- | Rulați | ||
- | |||
- | <code> | ||
- | jobs | ||
- | </code> | ||
- | |||
- | pentru a vedea toate procesele care se află în fundal. | ||
- | |||
- | Tastați | ||
- | |||
- | <code> | ||
- | fg | ||
- | </code> | ||
- | |||
- | pentru a aduce în foreground un proces din fundal. | ||
- | |||
- | După cum observați, se aduce ultimul proces trimis în fundal. | ||
- | |||
- | Trimiteți ''Ctrl-Z'' procesului ''vim'' din foreground. | ||
- | |||
- | Rulați comanda | ||
- | |||
- | <code> | ||
- | fg 1 | ||
- | </code> | ||
- | |||
- | Observați că se aduce primul proces trimis în fundal. | ||
- | |||
- | Aduceți ambele procese în foreground și ieșiți din vim. | ||
- | |||
- | |||
- | |||
- | ===== 13. bg. Variabila $! ===== | ||
- | |||
- | Rulați comanda | ||
- | |||
- | <code> | ||
- | cat /dev/random | ||
- | </code> | ||
- | |||
- | <note tip> | ||
- | Nu intrați în panică, rolul fișierului ''/dev/random'' este acela de a genera octeți aleatori. Este normal să vedeți caractere ciudate. | ||
- | </note> | ||
- | |||
- | Pe ecran vor fi afișate caractere random. Trimiteți procesul în fundal utilizând semnalul SIGSTOP (''Ctrl-Z''). | ||
- | |||
- | Observați că procesul a fost trecut în starea ''Stopped''. Rulând ''ps'', procesul apare în output. | ||
- | |||
- | Rulați comanda | ||
- | |||
- | <code> | ||
- | bg | ||
- | </code> | ||
- | |||
- | Procesul pornește din nou dar aveți acces la prompt. Procesul __rulează__ în background (puteți observa ușor acest lucru deoarece caracterele generate de ''/dev/random'' sunt afișate în terminal). | ||
- | |||
- | Trimiteți semnalul ''SIGKILL'' utilizând ''kill'' procesului ''cat'' din background. Știind că este ultimul proces din background, folosim comanda | ||
- | |||
- | <code> | ||
- | kill -9 $! | ||
- | </code> | ||
- | |||
- | deoarece ''$!'' este PID-ul ultimului proces aflat în background. | ||
- | |||
- | Diagrama următoare arată stările în care se poate afla un proces și cum se trece dintr-o stare în alta. | ||
- | |||
- | {{http://elf.cs.pub.ro/uso/store/lab4_stari_procese.png}} | ||
- | |||
- | |||
- | |||
- | |||
- | ====== Hands-on ====== | ||
- | |||
- | ===== 1. htop ===== | ||
- | |||
- | Deschideți o instanță de ''vim''. | ||
- | |||
- | Într-un alt terminal, rulați comanda<code>htop</code> | ||
- | |||
- | Observați că informațiile afișate sunt cele din top dar interfața este mult mai ușor de folosit. | ||
- | |||
- | Afișați detalii despre procesul ''vim'', detalii referitoare la fișierele deschise și la zonele de memorie folosite (folosiți tasta ''l'') | ||
- | |||
- | <solution>Selectăm procesul și tastăm ''l''</solution> | ||
- | |||
- | |||
- | |||
- | ===== 2. less. more ===== | ||
- | |||
- | Folosind ''ps'' determinați PID-ul procesului ''gnome-panel''. | ||
- | |||
- | **NU** folosiți scroll. Folosiți ''less'' sau ''more''. | ||
- | |||
- | Observați că ''less'' permite operații mai avansate decât ''more''. Utilizatorii spun "''less'' is ''more''" | ||
- | |||
- | <solution>ps -e | less</solution> | ||
- | |||
- | |||
- | |||
- | ===== 3. Pipe-uri cu nume ===== | ||
- | |||
- | Un tip special de fișiere unix sunt pipe-urile cu nume. Acestea au o reprezentare fizică pe disc. | ||
- | |||
- | Creați un pipe cu numele ''twitter''. <code>mkfifo twitter</code> | ||
- | |||
- | Listați în format lung informații despre acest fișier. Ce observați? | ||
- | |||
- | Deschideți un terminal și scrieți mesajul "USO rU1z" în fișierul ''twitter''. | ||
- | |||
- | Deschideți un alt terminal și afișați conținutul fișierului. Ce observați? | ||
- | |||
- | Încercați să afișați din nou conținutul fișierului. | ||
- | |||
- | Ce se întâmplă dacă revenim în primul terminal și încercăm să scriem un nou mesaj în fișier? | ||
- | |||
- | <solution> | ||
- | | Terminal 1 | Terminal 2 | | ||
- | | ls -l twitter | | | ||
- | | echo "USO rU1z" > twitter | | | ||
- | | | cat twitter | | ||
- | | | cat twitter | | ||
- | | echo "It works!" > twitter | | | ||
- | </solution> | ||
- | |||
- | |||
- | |||
- | ===== 4. Find out PIDs ===== | ||
- | |||
- | Folosiți ''ps'' și ''grep'' pentru a afla PID-ul terminalului curent. | ||
- | |||
- | Ce se întâmplă dacă aveți mai multe sesiuni deschise? | ||
- | |||
- | ''$$'' este o variabilă de mediu specială care conține PID-ul procesului curent. | ||
- | |||
- | Determinați PID-ul terminalului curent. | ||
- | |||
- | Determinați PID-ul procesului părinte. (folosiți variabila de mediu ''$PPID'') | ||
- | |||
- | Aflați numele procesului părinte. (''ps'' și ''grep'') | ||
- | |||
- | <solution> | ||
- | <code> | ||
- | ps -e | grep bash | ||
- | echo $$ | ||
- | echo $PPID | ||
- | ps -e | grep $PID #replace $PID cu cel obținut anterior | ||
- | </code> | ||
- | </solution> | ||
- | |||
- | |||
- | |||
- | ===== 5. pgrep ===== | ||
- | |||
- | Deschideți editorul ''vi''. | ||
- | |||
- | Într-un alt terminal, folosiți comanda ''pgrep'' pentru a afișa numele și pid-ul tuturor proceselor ''vi'' din sistem. | ||
- | |||
- | Căutați parametrul ''-l'' în man. | ||
- | |||
- | Cum ați putea afișa doar procesele ''vi'', fără a afișa și procesele ale căror nume conțin grupul de litere ''vi''? | ||
- | |||
- | Căutați în man după "exactly". | ||
- | |||
- | |||
- | ====== Rocket science ====== | ||
- | |||
- | ===== 1. pmap ===== | ||
- | |||
- | Se dă următorul program [[http://elf.cs.pub.ro/uso/store/hello.c | hello.c]]. | ||
- | |||
- | Compilați programul folosind <code>gcc -o hello hello.c</code> | ||
- | |||
- | Folosiți ''pmap'' pentru a vizualiza maparea memoriei virtuale. | ||
- | |||
- | Analizați sursa și încercați să explicați comportamentul. | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | ====== Hands-On ====== | ||
- | |||
- | ===== 1. Daemon. Informații ===== | ||
- | |||
- | <hidden> | ||
- | De ce avem daemoni? Ce sunt? | ||
- | </hidden> | ||
- | |||
- | Rulați programul descărcat anterior astfel: | ||
- | |||
- | <code> | ||
- | ./signal_test 42 | ||
- | </code> | ||
- | |||
- | Programul creează un daemon. Folosiți un procedeu pentru a afla PID-ul procesului creat. | ||
- | |||
- | <solution> | ||
- | <code> | ||
- | pgrep signal_test | ||
- | </code> | ||
- | </solution> | ||
- | |||
- | Observați că singura modalitate de a interacționa cu acesta o reprezintă semnalele. | ||
- | |||
- | Navigați către directorul din ''/proc'' corespunzător procesului. Listați filedescriptorii procesului, __în format lung__. Ce observați? | ||
- | |||
- | <solution> | ||
- | <code> | ||
- | $ cd /proc/$(pgrep signal_test) | ||
- | $ ls -l fd | ||
- | </code> | ||
- | </solution> | ||
- | |||
- | |||
- | |||
- | ===== 2. Daemon. Interacțiune ===== | ||
- | |||
- | Instalați pachetul ''apache2''. | ||
- | |||
- | Verificați că există un proces ''apache2'' care rulează. Acesta este un alt exemplu de daemon. | ||
- | |||
- | Folosind ''/etc/init.d/apache2'' opriți acest proces. Această formulare trimite un semnal daemonului Apache. Ca rezultat, daemonul se va închide. | ||
- | |||
- | <solution> | ||
- | <code> | ||
- | $ sudo apt-get install apache2 | ||
- | $ ps -e | grep apache2 | ||
- | $ sudo /etc/init.d/apache2 stop | ||
- | </code> | ||
- | </solution> | ||
- | |||
- | |||
- | |||
- | ===== 3. Nohup ===== | ||
- | |||
- | Porniți procesul corespunzător comenzii ''ping -c 10000 google.com'' într-un terminal. | ||
- | |||
- | Închideți acest terminal și verificați (folosind ''ps'' __și__ ''htop'') dacă procesul ''ping'' mai există. | ||
- | |||
- | <solution> | ||
- | <code> | ||
- | $ ping -c 10000 google.com | ||
- | Alt-F4 (Enter) | ||
- | $ ps -e | grep ping | ||
- | $ htop # căutam ping în output | ||
- | </code> | ||
- | </solution> | ||
- | |||
- | Încercați același lucru și trimițând procesul în background prin folosirea ''&''. | ||
- | |||
- | <solution> | ||
- | <code> | ||
- | $ ping -c 10000 google.com & | ||
- | Alt-F4 (Enter) | ||
- | $ ps -e | grep ping | ||
- | $ htop # căutam ping în output și nu-l găsim | ||
- | </code> | ||
- | </solution> | ||
- | |||
- | Încercați și folosind ''nohup'', trimițând procesul în background prin ''&''. | ||
- | |||
- | <solution> | ||
- | <code> | ||
- | $ nohup ping -c 10000 google.com & | ||
- | Alt-F4 (Enter) | ||
- | $ ps -e | grep ping | ||
- | $ htop # căutam ping în output și îl găsim | ||
- | </code> | ||
- | </solution> | ||
- | |||
- | <note>Folosirea ''nohup'' împreună cu ''&'' permite pornirea de procese ce nu vor fi terminate în momentul încheierii sesiunii curente.</note> | ||
- | |||
- | |||
- | |||
- | ===== 4. disown ===== | ||
- | |||
- | Rulați comanda ''ping 8.8.8.8 > /dev/null &''. Procesul este rulat în background. | ||
- | |||
- | Închideți acest terminal și verificați (folosind ''ps'' __și__ ''htop'') dacă procesul mai există. | ||
- | |||
- | <solution> | ||
- | <code> | ||
- | $ ping 8.8.8.8 > /dev/null & | ||
- | close terminal | ||
- | $ ps -e | grep ping | ||
- | </code> | ||
- | </solution> | ||
- | |||
- | Deschideți un alt terminal și rulați din nou ''ping 8.8.8.8 > /dev/null &''. Procesul rulează în background. | ||
- | |||
- | Folosiți ''disown'' pe pid-ul asociat procesului ''ping'', apoi închideți terminal-ul. | ||
- | |||
- | Ce se întâmplă cu procesul? | ||
- | |||
- | <solution> | ||
- | <code> | ||
- | $ ping 8.8.8.8 > /dev/null & | ||
- | disown $(pidof ping) | ||
- | close terminal | ||
- | $ ps -e | grep ping | ||
- | </code> | ||
- | </solution> | ||
- | |||
- | <note>''disown'' este o comandă built-in a shell-ului care face ca un proces să nu se termine în momentul încheierii sesiunii curente.</note> | ||
- | |||
- | |||
- | ====== Rocket Science ====== | ||
- | |||
- | ===== 1. Procese orfan ===== | ||
- | |||
- | Demonstrați, pornind procese și trimițând semnalele corespunzătoare, că părintele unui proces al cărui părinte este terminat este chiar procesul ''init''. | ||
- | |||
- | Hint: porniți un ''xterm'' din interiorul altui ''xterm'' pornit din terminal și terminați primul ''xterm'' pornit. | ||
- | |||
- | <note tip> | ||
- | Puteți folosi ''pstree'' pentru vizualizare rapidă sau ''ps'' afișând și ''PPID''. | ||
- | </note> | ||
- | |||
- | <solution> | ||
- | <code> | ||
- | 0$ xterm | ||
- | 1$ xterm | ||
- | </code> | ||
- | Se închide primul ''xterm'' pornit. | ||
- | <code> | ||
- | 2$ ps -eo cmd,pid,ppid | grep xterm | ||
- | </code> | ||
- | </solution> | ||
- | |||
- | |||
- | ===== 2. Screen ===== | ||
- | |||
- | Instalați pachetul ''screen''. Folosiți-l pentru a rula, în paralel, pagina de manual a programului ''screen'', o instanță de ''vim'' și procesul corespunzător comenzii ''ping google.com''. | ||
- | |||
- | Utilizând pagina de manual, determinați combinația de taste necesară pentru a părăsi ''screen'' fără a opri procesele care rulează. | ||
- | |||
- | Pentru a verifica, conectați-vă la sesiunea anterioară de ''screen''. | ||
- | |||
- | <solution> | ||
- | |||
- | Control-A Control-C creează o fereastră nouă | ||
- | |||
- | Control-A număr navighează la fereastra număr | ||
- | |||
- | Control-A Control-D detașează screen | ||
- | |||
- | Resume la o sesiune se face cu ''screen -r'' | ||
- | </solution> |