Note de curs, clasele 11-12, 5 iunie 2014

From Algopedia
Jump to: navigation, search

GNU/Linux, partea a doua

Vă reamintesc două resurse utile:

Filozofia Unix

Filozofia Unix este ca programele să facă un singur lucru și să-l facă bine. Puterea unui astfel de sistem de operare vine nu dintr-un singur program, ci din interacțiunea multor programe mici.

Desigur, și sub GNU/Linux au apărut programe-mamut, cum ar fi Gimp sau LibreOffice. Dar întotdeauna va exista nevoia pentru programe ca yes sau sort. De ce s-ar obosi un program să implementeze separat opțiunea yes to all când putem executa yes | program ? :-)

Scopul directoarelor

GNU/Linux folosește anumite directoare pentru anumite scopuri. De exemplu:

  • /home: directoarele personale ale utilizatorilor
  • /etc: fișiere de configurare globale ale programelor
    • fiecare utilizator își poate suprascrie aceste preferințe, de regulă prin fișiere "dot" (al căror nume începe cu ".") în directorul lor personal
  • /media, /mnt: partiții montate (discuri externe, flash drives)
  • /tmp: director temporar, unde oricine poate scrie/citi, și care este curățat la fiecare bootare
  • /usr: fișiere ale programelor instalate (binare, scripturi, biblioteci, imagini)
  • /var: date ale programelor instalate
  • /dev: dispozitive (devices). Nu sunt fișiere propriu-zise, dar descriu discurile și alte dispozitive fizice.
    • /dev/sd*, /dev/hd*: discuri
    • /dev/cdrom, /dev/cdrw, /dev/input/mice, /dev/event*: alte evenimente (demonstrație pentru mouse și tastatură)
    • /dev/random: generator de numere aleatoare bazat pe entropie
    • /dev/null: nimic :-)

Partiții

Pentru a putea folosi un disc, trebuie să-l partiționăm. Poate exista o singură partiție cât tot discul, sau mai multe partiții. Se poate chiar și ca o parte din disc să nu fie alocată niciunei partiții (și deci să fie inaccesibilă prin sistemul de fișiere).

Comanda fdisk are o interfață text pentru editarea partițiilor. Există interfețe mai deștepte, de exemplu gparted, dar fdisk este simplu.

$ sudo fdisk -l /dev/sda

Disk /dev/sda: 90.0 GB, 90028302336 bytes
255 heads, 63 sectors/track, 10945 cylinders, total 175836528 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x000d12bb

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048    92491775    46244864   83  Linux
/dev/sda2        92491776   167448575    37478400   83  Linux
/dev/sda3       167448576   175835135     4193280   82  Linux swap / Solaris

Odată create partițiile, putem crea sistemul de fișiere cu buchetul de comenzi mkfs.*. Din nou, gparted oferă o interfață grafică.

Tipul de partiție swap înseamnă că acea zonă de disc este dedicată memoriei virtuale. Pe ea nu va exista niciodată un sistem de fișiere (spre deosebire de alte sisteme de operare, unde memoria virtuală stă în fișiere care fac parte din partiția principală).

La ce sunt bune partițiile? De ce să nu facem o singură partiție pentru /? Iată câteva considerente pro și contra.

  • Directorul /home merită o partiție separată. Dacă peste câțiva ani vreau să reinstalez sistemul, pot să reinstalez cealaltă partiție, dar să păstrez intact directorul /home. Aceasta include toate bookmark-urile, configurările pentru aplicații, fișiere personale (poze etc.).
  • Partiții mai mici înseamnă că fsck va rula mai repede pentru fiecare din ele.
  • Dacă una dintre partiții devine coruptă și este pierdută iremediabil, celelalte rămân intacte.
  • Putem avea sisteme diferite de fișiere pe diverse partiții: unul criptat pentru /home, FAT32 pentru o partiție care trebuie să fie disponibilă și sub Windows etc.
  • Pe de altă parte, mai multe partiții înseamnă riscuri mai mari ca una dintre ele să se umple. Deci trebuie să ne estimăm mai bine nevoile.

Df, mount, umount, /etc/fstab

Montarea este procesul prin care kernelul decodează structura fișierelor de pe o partiție a unui disc și face acea structură disponibilă undeva într-un subdirector al sistemului de fișiere existent.

Cu comanda df putem vedea partițiile montate și informații despre ele. Cu df -h putem vedea rezultatele într-un format mai prietenos ('h = human-readable).

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        44G   15G   27G  37% /
none            4.0K     0  4.0K   0% /sys/fs/cgroup
udev            1.9G  4.0K  1.9G   1% /dev
tmpfs           388M  1.1M  387M   1% /run
none            5.0M     0  5.0M   0% /run/lock
none            1.9G  652K  1.9G   1% /run/shm
none            100M   20K  100M   1% /run/user
/dev/sda2        36G   29G  5.2G  85% /media/other

Comenzile mount și umount, rulate ca root, ne permit să montăm și să demontăm partiții. Acest caz intervine (cam des, din păcate) atunci când, dintr-un motiv sau altul, sistemul nu montează automat un stick de date, un hard disc extern, etc.

În /etc/fstab puteți citi și/sau modifica informațiile implicite de mount, de obicei stabilite la instalare.

Loguri

Orice program civilizat notează într-un fișier evenimentele importante care i se întâmplă. Astfel, dacă o avarie survine noaptea sau când nimeni nu este prin preajmă, administratorul poate investiga ce s-a întâmplat.

Logurile stau în /var/log. Dintre ele, menționăm:

  • /var/log/syslog și/sau /var/log/syslog: loguri de sistem
  • /var/log/apache2/*: logurile serverului web (dacă rulați Apache).
  • /var/log/mail.*: logurile serverului de mail (dacă rulați unul).

În general, fiecare serviciu care rulează pe GNU/Linux are propriul log.

Logurile sunt „rotite” după diverse reguli, vedeți /etc/logrotate.*. Aceasta înseamnă că, pentru a nu crește la infinit, fișierele sunt mutate la un interval (zilnic sau săptămânal), iar cele mai vechi de X rotații sunt șterse. Acest proces necesită puțină atenție, căci simpla redenumire a fișierului log și deschiderea unuia nou nu este suficientă. Dacă serviciul avea deja un FILE* către acel fișier, el va scrie tot în el și după redenumire! Este nevoie ca serviciile să repornească sau, mai elegant, să primească un semnal că trebuie să-și închidă/redeschidă logul.

Servicii

Serviciile sunt programe care stau rezidente în memorie, de obicei pe toată durata funcționării calculatorului și așteaptă să fie folosite. Exemple:

  • serviciul de ssh, prin care ne putem lega din afară pe un calculator
  • serviciul de ftp, prin care putem transfere fișiere (atenție, implicit el este insecure)
  • serviciul de mail, prin care putem primi și trimite e-mailuri
  • serviciul de SpamAssassin, prin care putem filtra e-mailurile sus-menționate
  • serviciul de web, prin care putem răspunde la URL-uri pe portul 80 (Apache, Nginx etc.)
  • serviciul de MySQL, prin care putem utiliza bazele de date MySQL
  • serviciul de NFS, prin care putem exporta anumite directoare de pe discul nostru pentru ca și un calculator extern să le poată monta.

etc., etc., etc.

Serviciile disponibile sunt listate în /etc/init.d. Puteți citi acele fișiere, sunt scripturi. Pentru a porni / opri / reporni un serviciu, executăm:

$ sudo /etc/init.d/apache2 restart

sau, în unele distribuții,

$ sudo service apache2 restart

Diverse servicii acceptă diverse comenzi. Dacă folosiți un interpretor de comenzi deștept, puteți tasta TAB-TAB după numele serviciului pentru a autocompleta comenzile disponibile (ca și la fișiere). În special comanda reload este utilă, dacă este implementată, întrucât îi spune serviciului să-și recitească fișierele de configurare, fără a se opri. Această metodă este mult mai rapidă decât o oprire + repornire, deci downtime-ul serverului va fi mult mai mic.

Find, tail, head, grep, sort, uniq, xargs, cut

Conform filozofiei Unix, aceste programe fac lucruri simple:

  • find: afișează recursiv fișierele dintr-un director
  • tail: afișează numai ultimele N linii ale unui fișier
  • head: afișează numai primele N linii ale unui fișier
  • grep: caută un text sau o expresie regulată în fișierul de intrare
  • sort: sortează liniile de la intrare și afișează-le la ieșire
  • uniq: elimină liniile adiacente identice, păstrând doar una din ele
  • xargs: execută o comandă pentru fiecare linie de la intrare, pasând-o ca parametru
  • cut: decupează câmpuri din fiecare linie, bazat pe niște delimitatori

Exemplul 1: Cum ștergem toate fișierele de backup (cele cu ~ la sfârșit):

$ find .|grep ~$|xargs rm -v

Exemplul 2: Când propun o problemă la Varena și scriu două-trei implementări, iată cum rulez o implementare pe toate testele ca să mă asigur că merge:

$ for i in {1..10}; do echo ===== Testul $i; rm problema.out; cp teste/grader_test$i.in problema.in; ./sursa-mea; diff -w teste/grader_test$i.ok problema.out; done

Exemplul 3: Când dexonline pare cam încărcat, iată cum aflu rapid statistici despre ce IP-uri îl vizitează cel mai intensiv:

dex@buddy:~$ tail -n 100000 /var/log/varnish/varnishncsa.log | cut -d ' ' -f 1 | sort | uniq -c | sort -nr | head -n 10
   1618 66.249.76.67
    412 157.55.39.142
    340 157.55.32.147
    335 157.55.39.39
    320 157.55.39.154
    289 86.121.174.205
    274 157.55.39.141
    263 157.55.39.9
    194 79.117.236.119
    193 79.113.121.181

Altele

  • Copy-paste: merge și cu mecanismul obișnuit (Ctrl-C / Ctrl-V), căci am ajuns la un nivel de maturitate unde majoritatea programelor suportă acest standard. Dar merge și selectare (click and drag, double click, triple click) + paste (middle click). Cele două clipboard-uri sunt diferite.
  • locate
  • procese
  • globbing: *, [...], {range}
  • back ticks
  • bash scripts; instrucțiuni repetitive