Sezione 1 : Introduzione
0.0 - Distribuzioni Linux : le differenze, e quale scegliere
- Debian, pacchetti in formato .deb e gestore apt;
- RedHat, pacchetti in formato .rpm e gestore yum;
- Arch, gestore pacchetti pacman.
Durante il corso verranno principalmente evidenziate le differenze tra RedHat e Debian.
0.1 - Scaricare, installare e configurare VirtualBox
Spiega come installare Virtualbox.
0.2 - Download ed installazione di Linux
Spiega come installare Ubuntu.
0.3 - Installazione VirtualBox Guest Additions e risoluzione problemi comuni
Avviamo la macchina virtuale e digitiamo nel terminale:
sudo apt update && sudo apt install build-essentials -yInseriamo quindi il cd delle guest-additions nella macchina virtuale e, se non parte automaticamente, eseguiamo il file autorun.sh (ci verrà chiesta la password di amministratore) poi si deve riavviare la macchina.
Qualche volta abbiamo la necessità di aggiungere il nostro utente al gruppo vboxsf con il seguente comando:
sudo usermod -aG vboxsf <nome-utente>IMPORTANTE : Problemi con VirtualBox
Elenco di alcuni problemi comuni utilizzando Virtualbox (e relativa soluzione).
Se dopo aver seguito le istruzioni per l’installazione delle VirtualBox Guest Additions alcune funzionalità come:
- appunti bidirezionali;
- cartelle condivise;
- drag and drop;
- copia/incolla.
Non dovessero funzionare, non preoccupatevi.
Queste funzionalità sono state mostrate per completezza e per massimizzare il vostro comfort nel caso in cui voleste scambiare dati da e verso la macchina virtuale, ma non sono necessari ai fini dello svolgimento del corso, in quanto non andremo mai a fare uso di tali funzionalità.
Se volete comunque provare a risolvere, l’approccio generalmente consigliato alla risoluzione dei problemi è il seguente:
- Ricerca VirtualBox nella sezione D&R: ci sono già numerosi casi trattati (e future richieste non riceveranno considerazione in quanto duplicate).
- Ricerca del codice dell’errore di VirtualBox (se presente) o descrizione della problematica (a più riprese e con diversi sinonimi) nella barra di ricerca di Google: come informatici o aspiranti tali è indispensabile imparare ad usare i motori di ricerca in maniera efficace. Serve perseveranza: non si trova sempre tutto al primo tentativo, è normale.
VirtualBox funziona solo a 32 bit
Questo problema è tipicamente causato dalle impostazioni del BIOS: alcuni produttori disabilitano la funzionalità virtualizzazione o VT-x ed è necessario andare ad abilitarla manualmente. Questa particolare procedura varia da computer a computer in base a marca e modello.
Questo problema può anche essere causato da una delle seguenti cause:
- abbinamento “sfortunato” tra versione di Windows e versione di Virtualbox;
- incorretta/corrotta installazione di VirtualBox;
- incompatibilità dell’hardware: non tutte le CPU supportano la virtualizzazione.
Questo genere di problema a seconda dei casi può essere più tedioso da risolvere, perciò sarà necessario un quantitativo non indifferente di ingegno da parte vostra: anche in questo caso valgono i consigli 1 e 2 del punto precedente.
Sezione 2 : 101 - Architettura del sistema
101.1 - Gli interrupts in Linux
Le periferiche comunicano con il processore tramite gli interrupts che ‘interrompono’ il processore per comunicare cosa stanno facendo (ad esempio l’interrupt della tastiera interrompe il processore ogni volta che si digita un tasto).
Il file /proc/interrupts (rigenerato ad ogni avvio del sistema) contiene (da sinistra a destra):
- il numero assegnato all’interrupt;
- quante volte questo ha interrotto il processore e quale processore/cpu;
- tipologia di interrupt;
- il nome dell’interrupt.
101.1 - ioports e DMA in Linux
File /proc/ioports
Una volta che il dispositivo lancia l’interrupt al processore, questo gli assegna un indirizzo di memoria in modo che possa essere utilizzata dalla periferica (sempre con la mediazione del processore). Gli indirizzi di memoria assegnati alle varie periferiche sono indicati nel file /proc/ioports.
File /proc/dma
Nelle macchine più recenti viene riservato un indirizzo di memoria che la periferica può utilizzare senza la mediazione del processore, questi indirizzi sono registrati nel file /proc/dma.
101.1 - dispositivi e drivers in Linux
- Dispositivi cold plug: devono essere collegati e scollegati quando il computer è spento.
- Dispositivi hot plug: si possono collegare a computer acceso (sono generalmente gli usb).
lspci # mostra i dispositivi collegati
lspci -t # mostra i dispositivi collegati in una struttura ad alberoDal kernel 2.6 i devices vengono creati dinamicamente e sono inseriti nella cartella /dev/.
UDEV crea automaticamente i device sotto /dev/ quando vengono collegati e comunica con lo userspace tramite il netlink socket quando sono caricati i devices.
Indipendentemente che siano hot-plug o cold-plug i vari dispositivi hanno bisogno di un driver per funzionare, quelli caricati sono visualizzati digitando il comando =lsmod= che elenca:
- il nome del modulo;
- la dimensione;
- da quanti dispositivi è utilizzato;
- il nome dei dispositivi che lo utilizzano.
I moduli che non sono utilizzati da nessun dispositivo possono essere rimossi dalla memoria tramite:
rmmod <nome-modulo>Per visualizzare la lista dei moduli non utilizzati:
lsmod | awk -F ' ' '{if ($3==0) print $0}' | lessPer inserire un mdulo invece si esegue il seguente comando:
insmod <full-path-to-module>Tutti i moduli si trovano all’interno della directory /lib/modules/<kernel-version>/ e posso cercarli tramite il comando:
find /lib/modules/$(uname -r)/ -iname "**<nome-modulo>*.ko*"Per caricare o rimuovere un modulo posso alternativamente utilizzare i seguenti comandi (più semplice perchè non serve il full-path):
modeprobe <nome-modulo> # per caricare il modulo
modeprobe -r <nome-modulo> # per scaricarloLa configurazione di un modulo (configurare gli interrupts oppure l’indirizzo dma da utilizzare con quel modulo) può essere fatta modificando/creando il file /etc/modeprobe.conf presente nella directory /etc/modprobe.d/.
sysfs è un file system montato dentro a /sys/ che contiene informazioni accessibili in modalità testuale relative ai devices. Risulta accessibile dallo =userspace= sia per le applicazioni che per gli utenti anche senza privilegi di root.
Digitare:
mount | grep sysPer verificare che sysfs è montato su /sys/.
Quindi ricapitolando: le applicazioni accedono ai device ed alle loro proprietà tramite la cartella /sys/ che, tramite dei simbolic-links ci fa accedere alle informazioni relative ai devices.
Dentro a /sys/ abbiamo quindi i devices divisi per categoria, tipo nei block-devices abbiamo le chiavette o i dischi e nella directory /devices/ abbiamo, appunto, i devices con molte informazioni a cui attingere.
All’interno della directory /sys/dev/ abbiamo sempre i devices ma con cui interagiscono i processi che, tramite link simbolici puntano al bus e alla directory del dispositivo.
101.1 - Spiegazione di D-bus, HAL, udev
- System-Bus, permette alle applicazioni di comunicare con l’hardware tramite HAL (harware abstraction layer, oggi UDEV).
- Session-Bus, permette alle applicazioni di comunicare tra di loro all’interno di una sessione di login.

Un’altra rappresentazione è tramite un ’tubo’ che permette ai vari comparti di comunicare.

Infine possiamo vedere dove si trovano D-bus e Udev (fagocitato da Systemd) tramite una rappresentazione ancora più complessa ma più completa.

101.2 - BIOS, EFI, Bootloader e runlevel
BIOS/UEFI
- BIOS, Basic Input Output System.
- UEFI, Unified Extesible Firmware Interface.
Sequenza di boot (BIOS)
- BIOS (16bit)
- POST Power On Self Test
- STAGE 1: boot loader (MBR primi 512 byte del disco principale)
- STAGE 2: boot loader SO (lancia il SO)
Alcune definizioni:
- initrd, initial ram disk;
- initramfs, init ram files system.
Il comando lsinitrd oppure lsinitramfs elencano il contenuto del relativo file.
Quando deve lanciare windows, GRUB in realtà non fa altro che caricare il bootloader di windows non essendo in grado di avviare propriamente windows.
EFI/UEFI boot
- EFI è un progetto abbandonato da Intel che lo ha portato in UEFI.
- Richiede una partizione UEFI in formato Fat32 con i flag boot ed esp.
bootloaders
Elenco dei bootloader di Linux per il BIOS:
- LiLo, (Linux Loader);
- GRUB, (GNU GRand Unified Bootloader) ora chiamato GRUB Legacy.
Elenco dei bootloader di Linux per UEFI:
- ELILO, (Efi Lilo);
- GRUB2.0, (che è l’evoluzione di GRUB e può fare il boot anche dal BIOS).
processo init
Il primo processo ad essere lanciato è init che ha il PID 1 e fa partire tutti gli altri processi. Rimane attivo fino allo spegnimento della macchina ed è chiaramente l’ultimo processo a morire.
Nei nuovi sistemi che utilizzano systemd il file /sbin/init è un collegamento simbolico a /lib/systemd/systemd. La stessa cosa può essere verificata analizzando il comando del primo processo avviato dal sistema tramite:
cat /proc/1/cmdline # contiene il file eseguito che è un collegamento al programma 'systemd'
cat /proc/1/comm # contiene il programma lanciato 'systemd' a cui è collegato il comando indicato in 'cmdline'Con systemd si utilizza il concetto di units, che possono essere definite come delle risorse di sistema che systemd è in grado di gestire. Queste risorse sono divise in varie categorie riconoscibili dal suffisso applicato al nome della unit, quali, a titolo esemplificativo e non esaustivo:
- .service;
- .socket;
- .device.mount;
- .automount;
- .target;
- .path;
- .time;
- e altre ancora.
runlevels
Ci sono 6 livelli di runlevel:
- 0, spegnimento;
- 1, single user x manutenzione;
- 2, multi user NO network;
- 3, multiuser network e testuale;
- 4, non in uso;
- 5, completo compreso la grafica;
- 6, reboot.
101.2 - Runlevel e diagnostica al boot
Per poter partire con un determinato runlevel posso modificare i parametri del kernel (digitare e in corrispondenza della relativa riga del menu di GRUB) aggiungendo alla fine della riga del comando il numero del runlevel in cui voglio partire (1|2|3|4|5).
Il file /etc/inittab contiene il runlevel di default.
Questo file era però utilizzato prima dell’avvento di systemd (anche se in realtà io ce l’ho ancora). Quindi per sapere il runlevel digitiamo:
systemctl get-defaultChe ci può restituire:
- multi-user.target, analogo al runlevel 3;
- graphical-target, analogo al runlevel 5.
Per cambiare il runlevel di default digitiamo:
systemctl set-default <nuovo-runlevel>Il seguente comando:
ls -l /lib/systemd/system/runlevel*.targetServe per vedere i runlevel che ci sono e che sostanzialmente puntano a dei target:
- runlevel0.target, poweroff.target;
- runlevel1.target, rescue.target;
- runlevel2.target, multi-user.target;
- runlevel3.target, multi-user.target;
- runlevel4.target, multi-user.target;
- runlevel5.target, graphical.target;
- runlevel6.target, reboot.target.
Se, alla fine della linea del kernel di GRUB, aggiungo init=/bin/sh, avrò l’avvio del sistema con una shell con privilegi di root (senza inserire la password di root!!!!).
All’interno del file /var/log/boot.log ci sono tutte le scritte che appaiono al boot, mentre il file /var/log/messages è un log globale da cui partire per cercare eventuali errori (sono presenti eventi dbus, eventi kernel ed altro).
Il comando dmesg digitato come utente root o preceduto da sudo fa vedere i messaggi del kernel (anche dopo il boot).
101.2 - Leggere i log con journalctl
journalctl è l’aggregatore dei log di sistema fornito da systemd.
Non è pratico usare journalctl senza opzioni in quanto il suo output risulta essere un’infinito elenco di log provenienti da qualsiasi elemento del sistema pertanto analizziamo le opzioni principali, utili a selezionarne gli elementi da visualizzare.
journalctl -b # mostra i log dal boot;
journalctl -br # mostra i log dal boot in ordine inverso (opzione =-r=);
journalctl --list-boots # mostra tutti i boot della macchina indicando un numero identificativo all'inizio della riga;
journalctl -b -<numero-boot> # per visualizzare un determinato boot;
journalctl --since="1 hour ago" # mostra i log dell'ultima ora;
journalctl --since="20 minutes ago" # mostra i log degli ultimi 20 minuti;
journalctl --since="2022-10-31" # mostra i log della data indicata;
journalctl --since="1 hour ago" --until="20 minutes ago" # mostra i log dell'ultima ora fino a 20 minuti fa;
journalctl _UID=<user-id> # mostra i log di un determinato utente.Tutte varie linee dell’output di journalctl non vanno a capo ma possono essere visualizzate se troppo lunghe utilizzando i tasti cursore <RIGHT> e <LEFT>.
L’opzione -k equivale all’opzione --dmesg e mostra (appunto) i messaggi del kernel (equivale al comando dmesg).
L’opzione -u <nome-unita> (oppure --unit <nome-unita>) visualizza i log di quella particolare unità.
Il comando systemctl lanciato da solo visualizza le unità in esecuzione.
All’interno dell’output di journalctl posso cercare ed evidenziare una stringa di testo premettendo il carattere / (N per cercare la ricorrenza successiva, n per cercare a ritroso).
Il comando journalctl -f serve per vedere in tempo reale i log (come per tail -f 'nome-log-file').
101.3 - Cambiare runlevel | System V init
Come detto in precedenza per cambiare runlevel al boot si mette il numerino alla fine della riga del kernel in GRUB.
Per i sistemi che utilizzano =systemd= possiamo cambiare il runlevel predefinito tramite:
systemctl set-default <nuovo-runlevel-predefinito>Mentre per i sistemi che utilizzano System V init devo modificare il numero di runlevel di default all’interno del file /etc/inittab e precisamente nella seguente riga:
id:5:initdefault:All’interno del file /etc/inittab possono essere configurati, per ogni runlevel, i comandi che vengono lanciati. Per i vari parametri utilizzati (es. respawn, wait, once) possiamo leggere la relativa pagina del manuale di inittab.
Per sapere in quale runlevel siamo (da root tramite su -) digitiamo il comando runlevel.
Per poter utilizzare il comando anche con sudo posso creare un collegamento simbolico tramite il seguente comando digitato da root:
ln -s /sbin/runlevel /usr/bin/runlevelAllo stesso modo posso sapere in che runlevel sono con il comando:
who -rPer cambiare il runlevel “al volo” invece utilizzo il seguente comando:
telinit <numero-nuovo-runlevel>La cartella /etc/init.d/ contiene tutti gli script che possono essere lanciati quando passo ad un determinato runlevel.
Le cartelle /etc/rc<numero-runlevel>.d/ invece contengono i collegamenti simbolici agli script che si trovano in /etc/init.d/ e che, a secondo di come è costruito il nome del collegamento, possono essere lanciati (lo script inizia con S) oppure “uccisi” (lo script inizia con K).
sysv-rc-conf è lo strumento che permette di configurare quali servizi vengono lanciati per quali runlevel, è la stessa cosa che creare/eliminare manualmente i collegamenti.
Analogamente esiste poi il comando chkconfig -l che però non trovo in Debian.
101.3 - Comandi shutdown e wall
Per spegnere la macchina è preferibile usare il comando shutdown che:
- prima manda un messaggio di broadcast a tutti gli utenti (15 minuti prima dello spegnimento) avvisando gli utenti collegati dell’imminente evento;
- poi cambia il runlevel tramite init;
- quest’ultimo comando manda un messaggio di SIGTERM a tutti i processi che si devono chiudere entro 5 secondi correttamente (utilizzare l’opzione
-tper cambiare questo parametro); - se i processi non si terminano da soli tramite SIGTERM manda un segnale di SIGKILL che uccide i processi in maniera brutale.
Vediamo un paio di esempi:
shutdown -c #annulla uno shutdown programmato
shutdown 17:01 "messaggio" # programma uno shutdown che verrà anticipato (15 min. prima) da un messaggio personalizzatoCon il comando wall, si può mandare in broadcast un messaggio personalizzato, per esempio:
wall "messaggio"All’interno dei doppi apici posso mettere anche delle variabili ($nome-variabile).
101.3 - Come funziona upstart
upstart rimpiazza System V init in Ubuntu e Fedora ma viene a sua volta rimpiazzato da systemd.
Alcuni servizi però non sono ancora stati migrati in systemd e continuano a funzionare con il sistema precedente. All’interno della cartella /etc/init/ troviamo questi servizi (io non ho la cartella).
Alcuni comandi per gestire i servizi con upstart:
stop <servizio>
start <servizio>
status <servizio>startup permette ai servizi di partire o fermarsi in determinate condizioni e con determinate regole ed al verificarsi di determinati eventi e non solo al cambiamento di runlevel.
Con il seguente comando:
initctl show-configPossiamo visualizzare queste regole per tutti i servizi configurati.
101.3 - Come funziona systemd
systemd parte dall’assunto di avviare un determinato servizio quando questo viene richiesto.
Molti demoni comunicano attraverso i socket, pertanto systemd associa ad ogni servizio un socket e lo avvia solo quando il suo socket riceve una richiesta.
Ad esempio mountfs monta un disco solamente quando qualche servizio ne fa richiesta e non prima.
Tutto quanto precede rende, almeno teoricamente, l’avvio del sistema più rapido.
Anche systemd è retro compatibile con inittab e, se presente, lo legge.
Ogni unit ha un’estensione che in qualche modo la identifica:
- .service;
- .socket;
- .device;
- .mount;
- .automount;
- .swap;
- .target;
- .path;
- .timer;
- .snapshot;
- .slice;
- .scope;
- e altre ancora.
Il comando principale per controllare le unit è systemctl, alcuni esempi:
systemctl status <nome-unity>
systemctl stop <nome-unity>
systemctl start <nome-unity>Alcuni cenni sulla struttura di un file di configurazione di una unit tipo <file>.service:
- After, il servizio deve essere lanciato dopo che sono partiti certi servizi;
- WantedBy, il servizio è richiesto (ad esempio) da alcuni runlevel.
Il seguente comando:
systemd-analyze blameCi dice quanto ogni servizio ha impiegato in fase di boot.
101.3 - SystemV “runlevels” vs “boot targets” di systemd
systemd sostituisce il concetto di runlevel con il concetto di boot target.
La seguente tabella sintetizza il boot target equivalente per ciascun runlevel:
| Runlevel | Target |
|---|---|
| 0 | poweroff.target |
| 1 | rescue.target |
| 2,3,4 | multi-user.target |
| 5 | graphical.target |
| 6 | reboot.target |
Su tutte le distro più recenti (dove systemd è il sistema di init di default) per cambiare boot target scriviamo alternativamente, ad esempio:
systemctl isolate multi-user.target
systemctl isolate graphical.targetE così via per gli altri target.
Per impostare un boot target predefinito (ad esempio, multi-user.target) dobbiamo prima di tutto abilitarlo e poi impostarlo come default:
systemctl enable multi-user.target
systemctl set-default multi-user.targetCome vedete è più semplice e intuitivo rispetto al vecchio concetto di runlevel.
101.3 - acpid
E’ un demone per gestire gli eventi ACPI (Advance Configuration Power Interface).
Gestisce gli eventi come aprire/chiudere il coperchio del portatile, premere tasti speciali, gestisce la connessione o disconnessione dalla rete elettrica e altro.
Da tener presente che certi Desktop Environment (come Gnome o KDE), oppure il login manager di systemd (il servizio systemd-logind) hanno i loro demoni e regole speciali per gestire questi eventi e che, questo demone potrebbe quindi andare in conflitto.
E’ quindi probabile che questo demone sia disabilitato, per verificare:
systemctl status acpid.servicePer configurare queste regole devo creare i relativi file di configurazione all’interno della cartella /etc/acpi/.
Test sul capitolo 101
Lezioni da n. 6 a n. 18.
Risposte giuste: 7 su 10.
Sezione 3 : 102 - Installazione di Linux e Package Management
102.1 - GNU Parted - alterare la tabella delle partizion
fdisk è pensato per lavorare con MBR:
fdisk -lCon la diffusione di GPT viene sempre più spesso utilizzato Parted.
parted -l # elenca i dischi presenti
parted /dev/sdb mklabel msdos # crea una tabella delle partizioni tipo msdos (MBR)
parted /dev/sdb -a cylinder mkpart primary linux-swap 2 102 # crea una partizione tipo swap di 100MB
parted /dev/sda print # visualizza le partizioni del disco
parted /dev/sda print free # visualizza anche gli spazi vuoti
mkswap /dev/sdb1 # per scrivere la partizione di swap
parted /dev/sdb mklabel gpt # cambia la tabella delle partizioni e cancella tutto il contenuto del discoUtilizzo di Parted in modalità interattiva:
parted
(parted) select /dev/sda
(parted) print
(parted) print free
(parted) mkpart
Tipo di partizione?
Tipo di file system?
Inzio? 2MB
Fine? 102MB
(parted) print
(parted) qAdesso la partizione non contiene nessun file system nonostante lo abbiamo selezionato, dobbiamo crearlo con il comando:
mkfs.ext4 /dev/sdb1Adesso posso montare la partizione ed utilizzarla.
102.1 - PARTED : Recupero partition table
IMPORTANTE
Dopo aver espanso una partizione con fdisk o parted non dimentichiamo di espandere anche il filesystem:
resize2fs /dev/sdaAll’opposto, prima di ridurre una partizione riduciamo il suo filesystem:
resize2fs /dev/sda 8GBQuindi, ricapitolando:
- fdisk e gparted permettono di modificare la partition-table, che è come un indice di dove inizia e finisce ciascun filesystem su disco;
- resize2fs è il tool che permette di espandere o ridurre il filesystem.
Quindi, ricapitolando ancora:
- ogni volta che riduciamo una partizione dobbiamo PRIMA ridurre il filesystem, POI la partition-table;
- ogni volta che la espandiamo dobbiamo PRIMA modificare la partition-table e DOPO anche espandere il filesystem fino alla fine della partizione.
esempio
parted /dev/sdb
(parted) print
(parted) rm
Partizione numero? 1Cancello erroneamente una partizione. Praticamente però è stata cancellata la riga della tabella delle partizione ma i dati sono presenti sul disco. Sarà quindi sufficiente ricreare la partizione esattamente come era per rendere nuovamente disponibili i dati.
dd if=/dev/zero of=/dev/sdb bs=512 count=1Il comando scrive tutti zeri sul primo blocco del disco (la tabella delle partizioni) che viene in tal modo cancellata.
Ricreiamo quindi la partizione allo stesso modo e la recuperiamo.
parted
(parted) print
(parted) mklabel
Tipo dell'etichetta del disco? msdos
(parted) mkpart102.1 - swap, swapfile e swappiness
getconf PAGESIZEE’ il comando che ci restituisce l’unità minima che il computer trascrive ‘a blocchi’. Nel mio caso risulta essere un valore di 4096 ovvero 4kb.
swapon -sCon questo comando vedo le partizioni swap ed il loro utilizzo. Il comando non fa altro che restituire il valore contenuto nel file /proc/swaps.
Come regola generale per decidere quanta swap utilizzare possiamo fare 1,5 o 2 volte la RAM, anche se, mano mano che cresce la RAM installata possiamo anche diminuire la dimensione della partizione swap.
Per creare una partizione swap su un disco /dev/sdb con il comando fdisk digitiamo:
fdisk /dev/sdb- quindi il comando
n(new partition) per creare la partizione (per conoscere l’elenco dei comandi di fdisk digitarem, la partizione swap ha il codice 82) - digitare quindi
wper scrivere le partizioni su disco
Il comando fdisk crea automaticamente la disk-label tipo msdos in quanto, come detto in precedenza, è un comando pensato per le tabelle MBR.
Ora devo creare il filesystem e dire a linux di utilizzare la partizione:
mkswap /dev/sdb1
swapon /dev/sdb1 # per attivare la partizione swap
swapoff /dev/sdb1 # per disattivarlaPer cambiare la priorità ad una partizione di swap digito:
swapon /dev/sdb1 -p <priorita>Cambiamento che vale sono fino al riavvio della macchina.
Per rendere la modifica permanente devo aggiugere sul file /etc/fstab mettendo l’opzione -p (priorita).
Nel file /etc/fstab si preferisce mettere l’UUID invece che /dev/sdXY perchè se, in fase di montaggio, cambia la priorità di montaggio dei vari dischi un disco /dev/sdb potrebbe diventare /dev/sdc non venendo quindi eseguita la relativa riga di /etc/fstab, questo non accade usando il riferimento UUID.
Per conoscere un UUID di una partizione esegui il seguente comando:
blkid /dev/sdb1Un paio di altri comandi:
swapoff -a # disattiva tutte le partizioni di swap
swapon -a # rimonta le partizioni di swap da 'etc/fstab'Anziché utilizzare una partizione come file di swap posso anche utilizzare un file:
dd if=/dev/zero of=/tmp/swapfile bs=10M count=10Con il precedente comando ho creato un file riempiendolo di ZERI (/dev/zero), quindi:
mkswap /tmp/swapfile # crea una UUID per questo file che viene impostato di tipo swap
swapon /tmp/swapfile # la procedura restituisce un warning per problemi di sicurezza
chmod 600 /tmp/swapfile # imposto permessi per cui solo il proprietario del file può leggere/modificare il file e rieseguo il comando precedenteE’ possibile anche controllare a quale soglia la partizione di swap deve entrare in funzione iniziando a ‘swappare’:
cat /proc/sys/vm/swappinessRestituisce un valore da 0 a 100, più il valore è alto e più la swap verrà utilizzata. Con un valore pari a 0 la swap verrà utilizzata solamente quando la RAM viene esaurita mentre un valore pari a 100 rende la swap molto più aggressiva ed entrerà in azione prima (non si sa bene quanto prima).
Per cambiare questo valore, come detto, dobbiamo modificare il valore del file di ‘swappiness’:
echo 30 > /proc/sys/vm/swappiness/Per cambiare permanentemente il valore di swappiness dobbiamo invece agire sul file /etc/sysctl.conf inserendo una riga simile alla seguente:
vm.swappiness=80102.1 - progettare il partizionamento dei dischi
Il comando df elenca le partizioni montate:
df -hTIn Linux esiste uno standard di come deve essere strutturato il filesystem partendo dalla radice (/) e lo possiamo trovare al seguente Link
. Stabilisce delle directory che troveremo sempre su sistemi Linux.
E’ abbastanza frequente trovare la cartella /boot/ su una partizione diversa in quanto, ad esempio, LVM (si veda capitolo successivo) non è supportato al momento del boot. LVM è infatti una architettura software ad alto livello che non è ancora disponibile in fase di boot.
Ci sono cartelle che dovrebbero avere la loro partizione e montate separatamente come, ad esempio, /home/ e /var/.
La cartella /var/log/ (ad esempio) può diventare molto grande quando qualche applicazione inizia a inviare messaggi log con una frequenza intensa per qualche errore. Questo può fare ingrandire la cartella fino a saturare il disco e, nel caso si tratti del disco dove è presente il sistema, può creare problemi di funzionamento del computer.
Per pesare il contenuto delle varie cartelle possiamo lanciare il comando du (seguono alcuni esempi da provare):
du -sh <cartella>/*
du -h <cartella>>/*
du -sh <cartella>/Posso quindi creare una nuova partizione sul disco e creare la relativa filesystem (tipo ext4).
Può capitare che la tabella delle partizioni caricata in memoria differisca da quella scritta sul disco (questo capita spesso quando quella su disco è stata appena riscritta), in questo caso dobbiamo riallineare le tabelle con il seguente comando:
partprobe /dev/sdbI passaggi da compiere per spostare i dati di una cartella su una partizione sono quindi i seguenti (ad esempio voglio spostare la cartella /home/ su una partizione diversa da quella dove risiede il sistema operativo):
- creo una partizione vuota su disco;
- monto la partizione creata su
/mnt/; - copio tutti i dati della cartella che voglio spostare (es.
/home/) sulla partizione appena montata su/mnt/; - rimuovo quindi tutto quanto nella cartella originaria
- smonto la partizione da
/mnt/e la rimonto sulla cartella che ho appena cancellato; - aggiorno il file
/etc/fstabin modo che al prossimo riavvio si monti automaticamente.
Comandi per copiare i dati:
rsync -arvh /home/ /mnt/
cp -Ra /home/ /mnt/Il comando rsync serve solitamente per fare i backup o per mantenere sincronizzate 2 cartelle pertanto posso anche rilanciarlo successivamente e, se ci sono state delle variazioni nell’origine, copierà solamente i dati incrementali.
Comando per cancellare tutti i dati:
rm -rf /home/*L’ultimo numero delle righe di montaggio delle partizioni di /etc/fstab indica l’ordine con cui fare il check delle partizioni che vengono montate pertanto il n. 1 andrà riservato doverosamente alla partizione /root/ e gli altri numeri (2,3,4,…) alle partizioni meno importanti.
102.1 - Cos’è e come funziona LVM

E’ buona cosa che i Phisical Volumes siano indicati come partizioni (es. /dev/sdb1) e non come disco nella sua interezza (/dev/sdb), anche quando il disco dovesse contenere una sola partizione.
Per poter essere utilizzata da LVM la partizione deve essere creata come tipo LV, ossia tipo 8e e non il solito 83 per le partizioni Linux classiche.
Con LVM si possono spostare i dati a caldo, ossia posso aggiungere un disco e allargare una partizione LVM senza spegnere la macchina.
LVM supporta anche lo striping ossia la possibilità di scrivere e leggere contemporanemanete su più dischi aumentando in questo modo la velocità di esecuzione dell’operazione.
LVM supporta anche la possibilità di fare gli snapshot a caldo, ossia dei backup a caldo delle varie partizioni.
102.1 - LVM: aggiungere e rimuovere dischi
LVM può essere usato in maniera interattiva semplicemente digitandone il comando:
lvm
lvm> helpL’utilizzo può anche essere da riga di comando ed esistono 3 gruppi di comandi che si riferiscono ed agiscono rispettivamente su:
- (p)hysical (v)olumes, comandi che iniziano per pv;
- (v)olume (g)roup, comandi che iniziano per vg;
- (l)ogical (v)olume, comandi che iniziano per lv.
Ad esempio, per analizzare la situazione digitiamo:
pvscan # per sapere quanti dischi fisici sono presenti
vgscan # per sapere quanti volume group esistono
lvscan # per sapere quante partizioni sono state createPosso quindi creare una partizione su un disco (es. /dev/sdb1) con tipo partizione Linux LVM (codice 8e) e creare il physical volume tramite il comando:
pvcreate /dev/sdb1Devo poi procedere con l’estensione del volume group per poter avere poi a disposizione questo ulteriore spazio da assegnare ai logical volume:
vgextend <nome-volume-group> /dev/sdb1Ora posso procedere con l’estensione del logical volume, esempio:
lvextend /dev/<volume-group>/<logical-volume> -L +8GPer estendere la dimensione di un volume group di 8GB.
Ora analizziamo cosa bisogna fare per poter, ad esempio, staccare un disco fisico che è caricato come physical volume.
Prima di tutto dobbiamo fare in modo che la somma totale dei =logical volume= lasci spazio almeno per togliere il physical volume. Ad esempio, se ho 2 dischi da 10GB ciascuno e voglio staccarne uno, tutte le varie partizioni create (i logical volume) sommate devono essere al massimo 10GB in modo che posso staccare tranquillamente un disco senza creare problemi.
Il comando per ridimensionare una partizione (i.e. logical volume) è il seguente:
lvresize /dev/<volume-group>/<logical-volume> -L -8GBI comando invece per rimuovere un disco o partizione:
pvmove /dev/sdb1 # sposta i dati eventualmente presenti sul disco
vgreduce <volume-group> /dev/sdb1 # riduce la dimensione del volume group
pvremove /dev/sdb1 # rimuove il disco fisico102.1 - La partizione EFI (ESP)
Sui computer moderni ormai abbiamo UEFI e non più BIOS.
La prima cosa che fa il computer quando si accende è cercare una partizione di tipo UEFI, ossia formattata fat32 e con i flag boot e esp.
All’interno di questa partizione va a cercare un eseguibile di tipo UEFI che è il bootloader (nel nostro caso GRUB) il quale fa partire il kernel ed il sistema operativo.
La partizione UEFI è solitamente montata sotto /boot/ ed entrandoci possiamo trovare altre cartelle fino ad arrivare ad un percorso simile al seguente: /boot/efi/EFI/.
Dove ci sono altre cartelle, una per ogni sistema operativo installato, oltre alla cartella /BOOT/ dove risiede l’eseguibile predefinito di UEFI che, dopo aver installato Linux è il bootloader di grub (anche se ha il nome di default di UEFI, tipo BOOTx64.efi).
102.2 - GRUB Legacy
GRUB fino alla versione 0.97 è chiamato GRUB Legacy.
Con i seguenti comandi:
parted -l
fdisk -lTroviamo quale partizione ha il flag boot, ossia quale partizione contiene il bootloader GRUB che fa partire il sistema operativo.
Posso installare GRUB alternativamente con:
grub-install /dev/sda # all'interno del MBR del disco (primi 512kb)
grub-install /dev/sda1 # su una partizioneNel secondo caso si esegue il c.d. chainload ossia un bootloader scritto nell’MBR che lancia un secondo bootloader scritto su una partizione.
Per fare il backup del MBR prima di sovrascriverlo posso eseguire il seguente comando:
dd if=/dev/sda of=/path/to/backup-file count=1 bs=512Quando appare il menu di GRUB posso premere e per entrare e modificare la relativa voce, premo nuovamente e per modificare la relativa linea di istruzioni.
Le varie voci del menu di GRUB sono all’interno del file /boot/grub/menu.lst.
All’inizio delle varie righe non commentate ci sono diverse istruzioni (poche) che hanno il seguente significato:
default 0, indica la voce di menu selezionata di default (0 è la prima voce);hiddenmenu, nasconde il menu (premere ESC per renderlo visibile, va commentata per rendere esplicito il menu);uuid, definisce la partizione di boot (dove si trova il bootloader del Sistema Operativo);root=UUID, (all’interno dell’istruzione kernel) definisce la partizione dove si trova il kernel).
Modificando il file menu.lst naturalmente non è necessario eseguire il comando update-grub (di fatto questo comando sovrascrive le nostre personalizzazioni).
uuid può essere sostituito con root (hd0,0) prima partizione del primo disco ma, come già detto, l’individuazione di una partizione tramite UUID è più sicura e quindi preferibile.
Il comando:
cat /proc/cmdlineMostra i parametri che sono stati passati al kernel.
Dal menu di GRUB posso digitare c per entrare in una shell minimale da cui posso, ad esempio:
grub> root (hd0,0) # reinstallare GRUB specificando la partizione dove di trova il bootloader del SO, ossia GRUB
grub> setup (hd0) # installare grub sul primo disco
grub> setup (hd0,0) # installare grub sulla prima partizione del primo disco
grub> kernel /boot/vmlinux root=/dev/sda1 # specificare la root del kernel
grub> initrd /boot/initrd # specificare l'immagine del ramdisk
grub> boot # fare partire il SO102.2 - Come funziona GRUB 2
Arrivato alla versione 0.97 GRUB ha smesso di essere sviluppato ed ha cambiato nome in GRUB Legacy.
Viceversa la versione attualmente in uso di GRUB deriva da GRUB2 che, a differenza di Legacy, permette la gestione di molte più situazioni quali UEFI/GPT.
Pertanto i comandi e le cartelle di GRUB2:
grub2install
grub2-mkconfig
ls /boot/grub2Sono oggi i quelli di GRUB (che è quindi lo stesso programma):
grub-install
grub-mkconfig
ls /boot/grub/GRUB2 conta i dischi partendo da 0 (come GRUB Legacy) ma conta le partizioni partendo da 1 (a differenza di GRUB Legacy che parte da 0).
In GRUB2 si può anche identificare il tipo di partizione, ad esempio (hd0,gpt1) oppure (hd0,msdos1).
GRUB2 supporta nativamente UEFI e le partizioni GPT.
Come per GRUB Legacy l’installazione viene eseguita con il comando:
grub2-install /dev/sdaIl file /boot/grub/grub.cfg (come viene scritto all’inizio del file):
#
#DO NOT EDIT THIS FILE
#
#It is automatically generated by grub-mkconfig using templates
#from /etc/grub.d and settings from /etc/default/grub
#All’interno del file viene anche indicato da quale file di configurazione è stata generata la parte di codice racchiusa, ad esempio:
###BEGIN /etc/grub.d/40_custom ###
...codice....
###END /etc/grub.d/40_custom ###Per approfondimenti:
102.2 - Menu di GRUB nascosto
A partire dalla Ubuntu 18 il menu di GRUB non viene visualizzato, in quanto disabilitato nelle impostazioni che si trovano all’interno del file /etc/default/grub.
Precisamente dobbiamo andare a cambiare la seguente impostazione:
GRUB_TIMEOUT_STYLE=hiddenChe non fa visualizzare il menu di GRUB (premere ripetutamente ESC al boot per visualizzarlo), con la seguente che invece rende visibile il menu di GRUB senza premere ESC:
GRUB_TIMEOUT_STYLE=menu102.3 - librerie condivise (shared libraries)
Nel sistema operativo Windows si chiamano dll, Dybamic Link Library.
Sono dei pezzi di software condivisi che sono messi a disposizione di tutti i programmi eseguibili che vengono installati. Se un programma richiede librerie esterne per poter funzionare (dipende quindi dalla presenza di tali libreria) viene definito Dinamically Linked Executebles, se viceversa può essere eseguito senza nessuna dipendenza da librerie esterne (ossia contiene tutte le librerie necessarie al suo funzionamento compilate al suo interno) viene chiamato Statically Linked Executeble.
E’ naturale che un programma compilato insieme alle librerie necessarie per eseguirlo avrà una dimensione maggiore di un programma che invece si appoggia a librerie esterne che vengono richiamate per l’esecuzione.
Il comando =ldd= ci mostra, per ogni comando indicato come parametro, le librerie necessarie ad un eseguibile, ad esempio:
ldd /bin/ln /bin/lsMostra le librerie necessarie per eseguire rispettivamente il comando ln ed ls.
Le librerie sono file che hanno generalmente estensione .so (shared object) e che si trovano in alcune cartelle tra le quali troviamo sempre le seguenti:
/lib/, in cui si trovano le librerie a 32 bit;/lib64/, in cui si trovano le librerie a 64 bit;/usr/lib/, dove si possono trovare altre librerie.
Quando viene installato un programma questo cerca nelle cartelle dove si trovano le librerie per vedere se sono già presenti quelle necessarie per il suo proprio funzionamento e, se non le trova, avvisa che sono necessarie e vanno installate (oppure, più spesso, il gestore dei pacchetti della nostra distribuzione si preoccupa di installarle).
Il file /etc/ld.so.conf contiene altri percorsi dove cercare se sono presenti altre librerie (viene inserito un percorso per ogni riga) pertanto può capitare che alcune applicazioni aggiungano la riga relativa al percorso dove installano le librerie necessarie al proprio funzionamento per future applicazioni che verranno installate.
Il comando ldconfig aggiorna tali percorsi nella cache leggendo, appunto, il file di configurazione /etc/ld.so.conf.
Il comando ldconf -p stampa invece a video l’elenco di tutte le librerie con il loro percorso.
Un modo meno invasivo e più rapido per aggiungere uno o più percorsi in cui cercare le librerie (senza dover cambiare il contenuto del file /etc/ld.so.conf e senza dover aggiornare la cache dei percorsi con il comando ldconfig) è configurare la seguente variabile d’ambiente:
export set $LD_LIBRARY_PATH="/lib2:/lib3:/lib4"I percorsi inseriti nella variabile vengono probabilmente letti prioritariamente permettendo, ad esempio, di copiare una libreria nel percorso specificato e modificarla per fare lavoro di sviluppo e tornare alla variabile originaria semplicemente azzerando la variabile d’ambiente.
102.4 - dpkg : installare e gestire pacchetti .deb
I pacchetti con della distribuzione Debian e derivate hanno estensione .deb.
Generalmente per scaricare un pacchetto dobbiamo conoscere l’architettura del nostro sistema, per conoscerla possiamo digitare il seguente comando:
uname -aDa cui possiamo capire se l’architettura è a 32 bit (x86) oppure a 64 bit (x86_64).
Alcuni comandi utili:
dpkg -i <nome-pacchetto> # per installare un pacchetto
dpkg --info <nome-pacchetto> # per avere ulteriori informazioni sul pacchetto, tra cui le varie dipendenze
dpkg --listfiles <nome-pacchetto> # elenca i file contenuti nel pacchetto
dpkg -S <percorso-file> # fornisce il nome del pacchetto da cui è stato scaricato il file indicato
dpkg -l # fornisce la lista di tutti i pacchetti installati sul sistema
dpkg -l tz* # filtra i pacchetti che iniziano con tz
dpkg -r <nome-pacchetto> # rimuove il pacchetto mantenendo i file di configurazione
dpkg --purge <nome-pacchetto> # elimina anche i file di configurazioneIl seguente comando, quando previsto dal pacchetto, procede alla sua riconfigurazione:
dpkg-reconfigure <nome-pacchetto>Proviamo a capire da quale pacchetto (e quale versione) è collegato il comando java:
which java # per vedere il percorso completo del comandoE’ probabile che il nome del comando sia in realtà un link simbolico ad un file, in questo caso un link a qualcosa del tipo /etc/alternatives/java per cui, per vedere il percorso di default collegato al comando java, eseguo:
update-alternatives --display javaE quindi posso digitare:
dpkg -S <percorso-java>E capire a quale pacchetto appartiene il comando.
Come sempre risulta utile leggere il file man del comando =dpkg= per scoprire le varie opzioni e le varie funzionalità.
102.4 - apt-get e aptitude
Il gestore di pacchetti di Debian è apt, questo comando, a differenza di dpkg, gestisce anche le dipendenze.
apt-cache
Iniziamo con vedere qualche esempio del comando apt-cache il quale esegue delle query sui pacchetti:
apt-cache search <stringa> # cerca pacchetti che hanno nel titolo o nella descrizione 'stringa'
apt-cache showpkg <pacchetto> # mostra informazioni sul pacchetto
apt-cache stats # mostra statistiche
apt-cache unmet # visualizza le dipendenze non soddisfatte (probabilmente tutti i pacchetti che vengono elencati hanno una dipendenza più recente a sostituirli e quindi va tutto bene)
apt-cache depends <pacchetto> # mostra le dipendenze del pacchetto (i pacchetti di cui necessita per essere installato
apt-cache rdepends <pacchetto> # mostra le dipendenze inverse (i pacchetti che necessitano del pacchetto in query per essere installati)
apt-cache pkgnames <stringa> # mostra i pacchetti il cui nome inizia per 'stringa'apt utilizza dei repository per fornirci tutte le informazioni di cui sopra, questi repository si trovano all’interno del file /etc/apt/sources.list e vengono aggiornati tramite il seguente comando:
apt-get update # aggiorna le cache dei repository
apt-get upgrade # aggiorna il sistemaapt-get
Ora vediamo esempi relativi al comando apt-get:
apt-get install <pacchetto> # installa anche le dipendenze e vengono segnalati anche i pacchetti suggeriti e raccomandati
apt-get -s install <pacchetto> # fa la simulazione dell'installazione
apt-get install -d <pacchetto> # scarica solamente i pacchetti nella directory `/var/cache/apt/archives`
apt-get clean # per eliminare tutti i file dalla cache
apt-get remove <pacchetto> # disinstalla il pacchetto
apt-get autoremove <pacchetto> # rimuove anche le dipendenze che non sono più necessarie
apt-get autoremove --purge <pacchetto> # vengono rimossi anche i file di configurazione (nota l'asterisco accanto al nome del pacchetto)aptitude
aptitude è un pacchetto più completo e funziona anche tramite interfaccia =ncurses=:
aptitude searche <stringa>
aptitude install <pacchetto>
aptitutde remove <pacchetto>
aptitude # senza parametri lancia la console102.4 - apt
In sostituzione di apt-cache, apt-get e aptitude ora abbiamo il solo comando apt che risulta essere più semplice da gestire:
apt # lanciato da solo da le informazioni sui principali utilizzi
apt search <stringa> # cerca tra i nomi dei pacchetti e le descrizioni
apt show <pacchetto> # mostra informazioni su un pacchetto
apt install <pacchetto> # installa un pacchetto e le sue dipendenze
apt list <stringa> # mostra i nomi dei pacchetti che rispettano i parametri di ricerca di 'stringa'
apt update # aggiorna la cache dai repository
apt upgrade # aggiorna il sistema
apt full-upgrade # differenza di upgrade rimuove anche le versioni precedenti e le dipendenze non più richieste102.5 - Guida a yum e rpm
Sulle distribuzioni RedHat, CentOS, Fedora, SuSe e derivate si usano pacchetti rpm.
I pacchetti rpm sono archivi cpio:
rpm2cpio <pacchetto> > <file> # crea un file che contiene tutti i file del pacchetto
cpio -i --make-directories > <file> # crea tutti file contenuti nel file precedente (anche le directory e le sottodirectory) rispetto alla directory root del sistemarpm
rpm, come dpkg per Debian non risolve le dipendenze e non scarica i pacchetti ma installa solo quelli già scaricati, vediamo qualche esempio:
rpm -qpi <pacchetto> # (q)uery (p)ackage (i)nformations: informazioni sul pacchetto
rpm -qpl <pacchetto> # (q)uery (p)ackage (l)ist: lista dei file contenuti nel pacchetto
rpm -ih <pacchetto> # installa il pacchetto
rpm -qa # (q)uery (a)ll: fa l'elenco di tutti i pacchetti installati
rpm -qi <pacchetto> # (q)uery (i)nformations: informazioni sul pacchetto installato
rpm -ql <pacchetto> # (q)uery (l)ist: lista dei file di un pacchetto installato
rpm -qf <percorso-file> # (q)uery (f)ile: restituisce il pacchetto da cui è stato installato un file
rpm -e <pacchetto> # (e)rase: disintalla un pacchettoyum
yum è il gestore dei pacchetti tipo apt per Debian ossia può gestire repository online e gestire le dipendenze. E’ stato definitivamente sostituito da dnf che, per la maggior parte dei casi, mantiene la stessa sintassi. Vediamo qualche esempio:
yum -help # stampa del testo di aiuto
yum search <stringa> # cerca una stringa all'interno dei nomi e delle descrizioni dei pacchetti
yum provides <file> # ci dice quali pacchetti contengono il file
yum info <pacchetto> # restituisce informazioni sul pacchetto
yum check-update # come 'apt-get update'
yum update # come 'apt-get upgrade'
yum list # elenca tutti i pacchetti
yum list <stringa> # cerca i pacchetti con la stringa nel nome
yum install <pacchetto> # installa un pacchetto
yum provides <percorso-file> # restituisce da quale pacchetto è stato installato un file
yum remove <pacchetto> # disinstalla un pacchettoVi sono poi delle installazioni c.d. “di gruppo”, ossia che raggruppano più pacchetti per installare un ambiente, ad esempio un Desktop Manager oppure tutto il necessario per un Server Web:
yum grouplist # visualizza tutti i gruppi di applicazioni (es. "Server Web")
yum groupinstall "Server Web" # installa tutto il necessario per ottenere il risultato, in questo caso un Server Web102.5 - DNF e zypper
Aggiornamento del corso: dnf ha sostituto definitivamente yum e, come detto, ha praticamente la stessa sintassi:
dnf search <stringa> # cerca una stringa all'interno del nome e della descrizione dei pacchetti
dnf install <pacchetto> # installa un pacchetto
....Al posto di yumdownloader è stato invece introdotto zypper che può fare tantissime cose, ad esempio:
zypper search <stringa> # cerca una stringa nel nome e nella descrizione dei pacchetti e le espone con un output più leggibile
zypper download <pacchetto> # fa il download del pacchetto nella cache ('~/.cache/zypp/packages/...')102.6 - Virtualizzazione vs Containerizzazione

La virtualizzazione avviene tramite un Hypervisor che espone alle macchine virtuali l’hardware virtualizzato, su ogni macchina virtuale troviamo quindi binari/librerie e applicazioni.
Nella containerizzazione il Container Daemon non virtualizza un intero sistema operativo ma solamente tutto quanto necessario all’esecuzione della singola applicazione.
Vediamo ora alcune differenze.


Alcune ulteriori informazioni sulle differenze:
- la containerizzazione avviene a livello software mentre la virtualizzazione a livello hardware;
- l’allocazione della memoria RAM è statica nel caso di virtualizzazione (ad ogni macchina virtuale assegno un tot di memoria anche se inutilizzata) mentre è dinamico per la containerizzazione quindi l’utilizzo sarà sempre inferiore;
- la virtualizzazione è completamente sicura in quanto isola l’intero sistema operativo e la relativa memoria RAM, nel caso della containerizzazione vi è un processo separato che esegue l’applicazione ma la memoria RAM viene condivisa con la macchina host, pertanto è potenzialmente meno sicuro.
102.6 - IaaS, PaaS, SaaS e concetti

- SaaS, Software as a Service, destinato agli utenti finali;
- PaaS, Platform as a Service, destinato agli sviluppatori;
- IaaS, Infrastructure as a Service, destinato agli amministratori.
Per meglio chiarire il significato delle sigle menzionate vediamo l’immagine seguente dove si evidenzia cosa viene gestito dal provider e cosa viene “autogestito” passando progressivamente da TUTTO a NULLA.

Alcuni termini:
- load balancing, si frappone tra le richieste di accesso al servizio ed i server che lo erogano bilanciando equamente il lavoro tra i vari server;
- cloud computing istances, sono le richieste ai provider di aggiungere risorse al cloud quando le richieste di accesso dovessero aumentare (la citata “scalabilità”);
- block storage, si può aumentare o diminuire la capienza del nostro disco senza dover cambiare lo stesso;
- cloud networking, al crescere del traffico posso richiedere un aumento di banda disponibile.
Proviamo a chiarire con una immagine dove si vedono notebook degli utenti che visitano un sito web che accede ad una struttura tipo IaaS, la nuvola che rappresenta internet, il load balancer (che gestisce il carico di lavoro sui vari server) ed i server stessi:

102.6 - Clonazione di macchine virtuali e accorgimenti
Una volta creata una macchina virtuale posso installare varie applicazioni e potrei volerla clonare tale e quale in modo da non dover ripetere le stesse configurazioni oppure potrei volerla esportare per poterla utilizzare in altro contesto magari con alcune configurazioni specifiche e diverse da quelle attuali.
clonazione
In caso di clonazione della macchina devo porre attenzione ad alcuni aspetti che, post-clonazione, devo personalizzare sulla macchina clonata quali:
- MAC address delle schede di rete che devo rigenerare;
- UUID dei dischi anch’esso da rigenerare (esistono varie utility tra cui tune2fs);
- hostname che, se utilizzo le macchine clonate sulla stessa rete deve essere diverso;
- chiavi ssh dell’host (vedi tutti file che iniziano con
/etc/ssh/ssh_host_*), per la rigenerazione delle chiavi devo eseguire il comandossh-keygen -Asulla macchina clonata; - UUID del dbus anch’esso da rigenerare con il comando
dbus-uuidgen --ensureche va a modificare il file/var/lib/dbus/machine-id; - installare nella macchina clonata le GuestAdditions (in caso di Virtualbox) oppure l’equivalente software in caso di WMware.
esportazione
In caso di esportazione della macchina virtuale viene creato un file *.ova che, in fase di importazione da parte di Virtualbox chiede alcune informazioni per personalizzare l’importazione (ad esempio chiede il n. di GB di RAM da mettere a disposizione o il n. di core del processore) come se si stesse creando la macchina virtuale ma, una volta creata, questa avrà già installati tutti i programmi e le personalizzazioni che erano state fatte prima della sua esportazione.
cloud-init
Questo è uno strumento per personalizzare per istanze di cloud.
Ad esempio Canonical (Ubuntu) permette di creare uno script di personalizzazione che viene eseguito ad ogni clonazione di una macchina virtuale. A esempio si può impostare che il sistema venga aggiornato all’ultima versione dei pacchetti (tramite apt), che vengano installati alcuni di essi e personalizzati alcuni file (come ad esempio l’hostname) in modo da facilitare le operazioni di post-clonazione citate sopra.
Test pratico 1 : Test sul capitolo 102
Lezioni da n. 20 a n. 38.
Risposte giuste: 12 su 15.
Sezione 4 : 102 - Comandi GNU e Unix3.
103.1 - cambiare shell
Il terminale (ambiente grafico) o la console (tty) sono aperte su una shell.
Posso sapere su quale shell sto operando consultando la variabile $SHELL che mi restituisce il percorso della shell in uso, ad esempio /bin/bash.
Nel file /etc/passwd è indicato all’ultimo campo la shell di default dell’utente.
Si può entrare in una shell ‘al volo’ digitandola, ad esempio digitando sh, bash, ksh, e le altre shell disponibili.
Per conoscere le shell disponibili sul sistema digito il seguente comando chsh -l che sfortunatamente nel mio caso non funziona ma suggerisce di consultare il file /etc/shells che naturalmente è modificabile da root.
Per cambiare la propria shell di default un utente può digitare il seguente comando:
chsh -s <percorso-nuova-shell>Il comando richiede la password dell’utente per poter procedere a modificare (con privilegi amministrativi) il file /etc/passwd variando (appunto) la shell di default (ultimo campo).
All’utente amministratore root è sufficiente invece digitare:
chsh -s <percorso-shell> <nome-utente>L’esecuzione del comando in questo caso non richiede nessuna password di conferma.
103.1 - entrare e uscire dalla shell
In linux abbiamo più modi per entrare ed uscire da una shell:
- avviamo un terminale in ambiente X (xterm, terminator, termius, tmux e altri);
- si può entrare dalla console (tty0, tty1 generalmente fino a tty7 di cui una riservata per l’ambiente grafico).
Digitando il comando ps le shell aperte sono individuate come rispettivamente:
- pst, se si tratta di terminali;
- tty, se sono console.
Per uscire da una shell abbiamo le seguenti opzioni:
- digitare exit;
- digitare logout (generalmente per uscire da tty o da una shell dove è stato fatto il login - esempio con
su -l); - premere la combinazione di tasti Ctrl-d;
- digitando
exec 'nome-comando'(quando termina l’esecuzione del comando la shell viene chiusa).
103.1 - Linux Bash Shell : Le variabili
In bash abbiamo alcune variabili d’ambiente come ad esempio $USER oppure $PATH.
Per visualizzarle tutte digitare doppio TAB dopo avere digitato il carattere $ in quanto funziona il completamento automatico.
E’ buona abitudine impostare le nostre variabili in minuscolo per non andare a confliggere con le variabili d’ambiente che sono sempre in maiuscolo.
Vediamo qualche comando ed il suo significato:
env # mostra le principali variabili d'ambiente ed il loro contenuto
nomevariabile="contenuto-assegnato" # imposta il valore di una variabileLa variabile impostata in questo modo è visibile solo nella sessione della shell in cui viene assegnata (stesso PID). Per poterla rendere visibile anche nelle sessioni figlie dobbiamo esportarla, operazione che può essere fatta anche in fase di assegnazione:
export <nome-variabile> # rende accessibile la variabile anche nelle shell figlie
export nomevariabile="contenuto-assegnato" # esportazione di una variabile in fase di assegnazione del suo valoreIl seguente comando:
ps --forestMostra l’albero delle shell figlie nel terminale dove lancio il comando. Per rimuovere il valore assegnato ad una variabile e renderla così ‘vuota’ utilizzo il seguente comando:
unset nome-variabilePer vedere tutte le opzioni di shell digitiamo il seguente comando:
set -oQuando c’è il segno + significa che l’opzione è disattivata, mentre quando ho il segno - significa che l’opzione è attiva.
Alcune opzioni:
- allexport, definisce se una variabile deve essere o meno automaticamente resa disponibile alle shell figlie;
- noclobber, avvisa quando si sovrascrive un file.
La variabile $SHELLOPTS contiene le opzioni di shell attive.
103.1 - Bash Shell : gli alias
type ls # ci dice che tipo di eseguibile è il comando 'ls'
alias ls # ci dice quale alias corrisponde ad 'ls'
alias # mostra tutti gli alias attivi
\ls # esegue il comando 'ls' e non il suo alias
unalias ls # elimina l'alias 'ls'
alias ls='ls --color' # definisce nuovamente l'alias 'ls'Per rendere le modifiche permanenti queste devono essere inserite nel file di configurazione <homedir>/.bashrc che viene caricato ogni volta che faccio il login in una shell.
Il comando shopt invece mostra altre impostazioni della shell tra cui expand_aliases che è generalmente in stato on. Questo significa che gli alias che sono configurati verranno utilizzati.
Per non utilizzare gli alias configurati posso disabilitare questa opzione con il seguente comando:
shopt -u expand_aliasesPer riattivare l’opzione digito invece il comando seguente:
shopt -s expand_aliases103.1 - La bash history
L’elenco dei comandi della =history= si trova nel file ~/.bash_history.
history # elenca i comandi della history dal meno recente al più recente
!20 # esegue nuovamente il comando contrassegnato con il n. 20
!$ # corrisponde all'ultimo parametro passato al comando precedente
!! # esegue nuovamente l'ultimo comando presente nella history
!apt # esegue nuovamente l'ultimo comando che iniziava con aptPer eseguire ricerche nella history premo la combinazione di tasti Ctrl-r che esegue una ricerca progressiva a ritroso nella history man mano che digito i caratteri cercando quanto digitato all’interno dei vari comandi presenti nella history.
Durante la ricerca posso premere:
- Ctrl-r, per cercare la successiva occorrenza a ritroso;
- INVIO, per eseguire il comando trovato e visualizzato;
- ESC, per uscire dalla ricerca e visualizzare quanto trovato e magari modificarlo prima di eseguirlo;
- Ctrl-c, per uscire dalla ricerca.
Per azzerare la history eseguo il seguente comando:
history -cIn una shell di tipo bash è attivata di default l’opzione histexpand che permette l’interpretazione (espansione) del carattere !:
set +o histexpand # per disattivare l'opzione
set -o histexpand # per riattivarlaPer visualizzare le varie opzioni presenti nella propria sessione di shell:
shopt # per visualizzare tutte le variabili ed il loro stato (on/off)
echo $BASHOPTS # per visualizzare solo le opzioni attiveIl comando che inizia con uno SPAZIO viene eseguito ma non viene registrato nella history.
103.1 - man e uname
Il comando uname fornisce informazioni sul sistema:
uname --help # chiarisce quali informazioni fornisce a seconda delle opzioni utilizzate
uname -a # fornisce praticamente tutte le informazioni
uname -r # fornisce la versione del kernelL’ultimo comando risulta utile da espandere all’interno di qualche istruzione dove (appunto) è necessaria la versione del kernel in uso come nell’esempio seguente:
apt install linux-headers-$(uname -r)Il comando man visualizzare il manuale di qualsiasi comando linux che ne abbia uno abbinato.
Non tutti i comandi hanno un manuale e quando esiste è generalmente più completo ed esaustivo dell’utilizzo dell’opzione –help.
All’interno di man possiamo cercare qualcosa premendo il carattere / e digitando una stringa di ricerca seguita dalla pressione del tasto INVIO poi possiamo premere n per passare al risultato successivo oppure N per passare a quello precedente.
Per uscire dalle pagine del manuela premiamo q.
which <comando> # fornisce il percorso all'eseguibile di un comando
whereis <comando> # oltre all'eseguibile ci dice anche dove si trova il file di man103.1 - Quoting in bash
I metodi di quoting sono 3 e sono interscambiabili a seconda dei casi e delle necessità.
Il simbolo di escape (**) fa in modo che il carattere immediatamente successivo ad esso non venga interpretato dalla shell.
Ad esempio posso creare una directory con un nome che contiene degli spazi come segue:
mkdir nome\ directoryGli apici singoli (') fanno in modo che ciò che è contenuto tra di essi non venga interpretato in alcun modo da bash e venga riportato tale e quale.
I doppi apici (") invece interpretano solamente i seguenti caratteri:
$, espansione di una variabile o di un comando (es. $USER oppure $(date));`, un modo alternativo di espandere un comando (es. `date`);', come già detto impedisce che il carattere successivo venga interpretato;!, è il simbolo che permette l’espansione della history.
Non interpreta invece tutti gli altri caratteri quali, ad esempio, i seguenti: ><|&;:[]{}.
Alcuni esempi su quanto visto sopra:
echo $USER
echo '$USER'
echo $(date)
$ echo `date`
$ echo '`date`'
echo "$USER mi deve $5"
echo "$USER mi deve \$5"Per approfondimenti: https://www.gnu.org/software/bash/manual/html_node/Quoting.html
103.2 - expand e unexpand
I comandi expand e unexpand servono a uniformare all’interno di un file l’utilizzo degli spazi o del tabulatore.
Se, inserendo del testo o del codice in un file, utilizzo la barra spaziatrice più volte oppure utilizzo il tabulatore non ho apparentemente nessuna differenza da un punto di vista visivo anche se i caratteri utilizzati non sono gli stessi.
Per poter visualizzare l’utilizzo di un carattere nascosto (es. il tabulatore) posso utilizzare l’opzione -A del comando cat, ad esempio:
cat -A <nome-file>Ora vediamo l’utilizzo dei comandi citati in concreto:
expand <file> > <file-expanded> # sostituisce agli spazi le tabulazioni
unexpand <file> > <unexpanded-file> # sostituisce alle tabulazioni gli spazi103.2 - dividere e unire file con split e cat
A volte può essere utile dividere un file di testo in più righe oppure spezzare un file binario eccessivamente grosso per poi riunirlo in un secondo momento (magari per inviarlo via email a pezzetti).
Per fare gli esempi utilizzeremo un file di testo creato con il seguente comando:
for l in $(seq 4500) ; do echo "riga numero $l" >> textfile.txt ; done
wc -l textfile.txt # verifica che il file abbia 4500 righesplit ha la funzione di dividere un file in piccoli file, vediamo come:
split textfile.txt # suddivide il file in più file di 1000 righe ciascuno (l'ultimo ne avrà 500)
wc -l x* # verifica numero di righe in ogni file creato ed il loro nome (che inizia per 'x')
split textfile.txt -l 100 # specifica di quante righe deve essere ogni file
cat x* # stampiamo a video l'elenco di tutti i file come fosse una ricostituzione del file originale
split textfile.txt -l 100 <nome.file_> # specifica come devono iniziare i nomi dei file spezzati (a cui split aggiunge la numerazione 'aa', 'ab', ...)Per dividere un file binario qualsiasi (archivio, video, audio o altro) eseguiamo:
split -b 5m nomebinario.mp4Dove l’opzione -b specifica che si tratta di un file binario e 5m specifica la dimensione di ogni file spezzettato.
Se provo a digitare il comando:
file *Posso osservare che solo il primo file della sequenza spezzata contiene l’header che descrive il contenuto del file (multimedia) in quanto gli altri pezzi non sono identificabili. I file così divisi non sono accessibili fino a che non vengono riuniti con il seguente comando:
cat <files-da-concatenare> <file-riunito>103.2 - Le meraviglie di cut
Il comando cut ritaglia in base alle colonne un file di testo:
cut -c2 <nome-file> # visualizza la colonna 2 di ogni riga di un file
cut -c12-15 <nome-file> # visualizza un range di colonne
cut -c12- <nome-file> # visualizza da una colonne fino alla fine di ogni riga
cut -c-11 <nome-file> # visualizza dall'inizio della riga fino ad un carattereQuando abbiamo un file in cui ogni riga vi sono dei campi con un determinato separatore di campo, tipo nel file /etc/passwd posso specificare il delimitatore con il seguente comando:
cut -d':' -f1 <nome-file>Che visualizza il primo campo (o field) con l’opzione -f1 e specifica come delimitatore il relativo carattere :.
Posso ottenere la stessa cosa utilizzando la redirezione del flusso come segue:
cat <file> | cut -d':' -f1La redirezione dell’output può essere fatta con qualsiasi comando che accetti un flusso dallo standart input. Siccome cut produce un flusso dallo standard output posso anche ordinarlo aggiungendo il relativo comando:
cat <file> | cut -d':' -f1 | sortPer visualizzare più campi:
cat <file> | cut -d':' -f1,7 # visualizza le colonne 1 e 7
cat <file> | cut -d':' -f1-3 # visualizza le colonne 1,2,3Se alcune righe del file hanno il carattere separatore ed altre no, quelle che ne sono sprovviste vengono visualizzate per intero. Aggiungendo il parametro -s specifico che, qualora non esista il separatore dei campi indicato, non venga visualizzato la relativa linea:
cat <file> | cut -d':' -s -f1,7L’opzione --complement permette di stampare gli altri campi che non sono stati filtrati, esempio:
cat <file> | cut -d':' --complement -s -f1,7Visualizza tutti i campi ad eccezione del campo 1 e 7.
Infine posso anche specificare un mio delimitatore personalizzato da utilizzare in fase di output:
cut -d':' -s -f1,7 --output-delimiter=' # ' <file>103.2 - Formattare file di testo con fmt
Il comando fmt serve a riformattare un file di testo:
cat <file> | fmt # formatta il testo a 75 colonne andando a capo con la parola intera ma allunga le righe corte, sempre entro le 75 colonne
cat <file> | fmt -w 30 # specifica il numero delle colonne (se una parola singola ha più caratteri la lascia da sola e sfora il parametro)
fmt -w 1 <file> # di conseguenza visualizza parola per parolaAd esempio possiamo provare a rendere leggibile dmesg tramite:
sudo dmesg | fmt -w 100 # va a capo con la parola intera ma dove il comando è corto riempie la riga con il comando successivo
sudo dmesg | fmt -w 100 -s # dove il file originale va a capo lo forza anche nell'output
sudo dmesg | fmt -w 100 -s | less # il file è anche scorribile e ricercabile utilizzando le funzioni di less103.2 - head e tail
Comandi essenziali per vedere i log su Linux: head e tail.
Per vedere i primi messaggi (quelli più vecchi), la testa (‘head’) del file:
sudo head /var/log/messages # vede le prime 10 righe di default
sudo head /var/log/messages -n 5 # vede le prime 5 righeAlla stessa maniera tail mostra la fine (coda o ’tail’) di un file:
sudo tail /var/log/messages # vede le ultime 10 righe di default
sudo tail /var/log/messages -n 5 # vede le ultime 5 righeL’opzione follow aggiunta al comando tail permette di seguire in tempo reale l’aggiunta di nuove righe di log al file indicato:
sudo tail -f /var/log/messages # se il file non esiste da errore
sudo tail -F /var/log/messages # segue il file anche se non esiste avvisandoSe passo al comando tail 2 file il comando li segue entrambi:
tail -f <file-1> <file-2> # avvisandoci ogni volta quale file è stato modificato
tail -f -q <file-1> <file-2> # l'opzione '-q' non specifica ogni volta quale file viene modificato ma visualizza solo la modifica103.2 - Comando tr in GNU/Linux
Il comando tr lavora con i caratteri, l’utilizzo principale è nella seguente forma:
cat <text-file> | tr <SET1> <SET2>Il comando sostituisce ai caratteri di ‘SET1’ con i caratteri di ‘SET2’.
La prima e seconda stringa devono contenere lo stesso numero di caratteri e questi sono confrontati uno alla volta: il primo carattere di ‘SET1’ viene sostituito dal primo carattere di ‘SET2’ e così via.
Nel caso ‘SET2’ contenga un maggior numero di caratteri verranno ignorati quelli che eccedono, non è chiaro invece il comportamento in caso di maggiore lunghezza della stringa ‘SET1’.
Esempio di altri utilizzi:
cat <text-file> | tr [:lower:] [:upper:] # visualizza il file con tutti caratteri maiuscoli
cat <text-file> | tr [:lower:] [:upper:] > <new-file> # crea 'new-file' con tutti caratteri maiuscoli
cat <text-file> | tr -d '.' # elimina il carattere indicato '.'
cat <text-file> | tr -d '.d' # elimina i due caratteri indicati '.' e 'd'
cat <text-file> | tr -dc '.' # elimina tutto tranne il carattere indicato '.' (funzione complementare)
cat <text-file> | tr -dc [:print:] # elimina tutto i caratteri non stampabili (tutti quelli nascosti, compreso a capo riga)
cat <text-file> | tr -s ' ' # riduce ad un solo spazio/carattere quando ve ne sono più di uno consecutivi
cat <text-file> | tr -sd <SET1> <SET2> # elimina i caratteri di 'SET1' e riduce a 1 solo i caratteri di 'SET2'Per ottenere informazioni sul funzionamento di tr possiamo, come spesso accade, attingere a diverse fonti:
tr --help
info tr
man tr103.2 - Comando nl e wc
nl
nl <file> # mette un contatore di riga a sinistra di ogni riga
cat <file> | nl > <nuovo-file> # come sopra e salva tutto in un 'nuovo-file'
nl -i2 <file> # incrementa di 2 il contatore ogni riga
nl -s. <file> # mette un punto ('.') dopo il contatore
nl -s'> ' <file> # mette la stringa tra gli apici dopo il contatore
nl -w2 <file> # mette il contatore alla seconda colonna (default 6)
nl -nrz <file> # mette gli zero davanti alla numerazionewc
wc <file> # restituisce numero righe, parole e caratteri (byte)
cat <file> | wc # come sopra
wc -w <file> # restituisce il numero di parole
wc -L <file> # restituisce il numero di caratteri di cui è composta la riga più lunga
wc -c <file> # restituisce il numero di caratteri (o byte)103.2 - less, sort, uniq
sort <file> # ordinamento alfabetico delle righe
cat <file> | sort # ordina il file esattamente come sopra
sort -r <file> # ordinamento alfabetico inverso, da non confondere con
sort -R <file> # ordinamento casuale
du -s /home/max/* | sort -n # ordina per numero crescente (quello all'inizio della riga)
sort -k 2,2 <file> # ordina in base al secondo campo (campi separati da spazi)
sort -k 2 <file> # ordina la riga a partire dal secondo campo (non considera il primo campo nell'ordinamento)
cat <file> | sort | uniq # mostra solo valori di riga unici (non mostra i duplicati consecutivi, ecco perchè è preceduto da 'sort')
cat <file> | sort | uniq -d # mostra solo le righe che presentano duplicati consecutivi
cat <file> | sort | uniq | wc -l # conta i valori unici del file103.2 - paste, od, pr
paste
paste <file> # come 'cat' visualizza il contenuto del file
paste -s <file> # sopprime il carattere '\newline' visualizzando tutto su una riga e separando con una tabulazione le righe
paste -s <file> -d, # separa le righe del file originale con il carattere ','
cat <file> | paste - - # accorpa 2 righe per volta su 2 colonne (utile per righe originarie corte ovviamente)
cat <file> | paste - - - # accorpa 3 righe per volta su 3 colonne
cat <file> | paste - - - -d,:- # accorpa 3 righe per volta su 3 colonne ed imposta il separatore che viene utilizzato in sequenza (prima ',' poi ':' poi '-' e poi di nuovo da capo)od
od -b <file> # rappresenta il file in ottale (octal dump)
od -x <file> # rappresentazine in esadecimalepr
Il comando pr è un impaginatore per la stampa o visualizzazione di un file di testo:
pr <file> # impagina un file mettendo anche un'intestazione con DATA NOME-FILE N-PAGINAA titolo di esempio, una volta configurato numero di righe e colonne ottimali, è possibile visualizzare un file di testo decentemente formattato tramite less (utilizzare Pag-Up e Pag-Down), digitando quanto segue:
cat <file> | fmt -w 78 -s | ts ' ' | pr -W 82 -l 45 | less103.2 - Introduzione a sed
Tra le risorse della lezione vi è un link alla playlist Corso base SED - Manipolare testo, input e output shell in cui vi sono n. 8 lezioni dedicate al comando =sed= che vanno seguite prima di fare la lezione stessa.
lezione 1: Sintassi Espressioni Regolari
Le espressioni regolari sono uno standard POSIX/UNIX che ci permettono di individuare un pattern di testo, ad esempio:
- tutte le parole che iniziano con una maiuscola
- tutte le parole che finiscono con una maiuscola
https://regexr.com : è un sito dove ci si può esercitare a scrivere le espressioni regolari.
Ad esempio per selezionare in un testo sia la parola color che colour:
color|colour, il modo più semplice;colou?r, il punto interrogativo vale se ci sono zero o una corrispondenza del carattere che precede;colou*r, l’asterisco vale se ci sono zero o più corrispondenze del carattere che precede pertanto selezionerà, oltre a color e colour, anche colouuuuur.
Significato dei caratteri:
?, seleziona quando il carattere che precede trova 1 oppure 0 corrispondenze;*, seleziona quando il carattere che precede trova 0 o più occorrenze;+, seleziona quando il carattere che precede trova 1 o più corrispondenze;., seleziona qualsiasi cosa tranne a capo riga (ci deve comunque essere qualcosa);{1,3}, vale quando il carattere che precede trova da 1 a 3 occorrenze.
L’utilizzo delle parentesi quadre [] significa individuare uno dei caratteri indicati:
[.], in questo caso cerca il punto (i caratteri all’interno delle parentesi quadre non vengono interpretati);[ciao], seleziona tutti caratteri c, i, a, o;[a-z], seleziona tutte le lettere minuscole;[A-Z], seleziona tutte le lettere maiuscole;[0-9], seleziona tutti i numeri;[a-z]|[A-Z], seleziona tutte le lettere minuscole o le lettere maiuscole;[A-Z][a-z]+, seleziona tutte le parole che iniziano con una maiuscola;[^a], seleziona tutti i caratteri tranne a;[^A-Z], seleziona tutti i caratteri tranne le lettere maiuscole;[^A-Z ], seleziona tutti i caratteri tranne le lettere maiuscole e lo spazio.
Vi sono 2 simboli speciali (tra tanti):
^, utilizzato senza parentesi quadre individua l’inizio della stringa o del file;$, utilizzato senza parentesi quadre individua la fine della stringa o del file;^E, seleziona il carattere E se è il carattere iniziale della stringa o del file;.$, seleziona qualsiasi carattere che si trova alla fine della stringa o del file.
All’interno delle parentesi tonde si possono individuare singoli =pattern= e valutarli insieme ad altri:
(pattern1)|(pattern2), seleziona il testo che corrisponde al pattern1 oppure al pattern2.
lezione 2: SED | sostituire una parola
sed è uno stream editor, ossia individua dei pattern di testo in un file per poi esegue su di essi delle istruzioni e dei comandi che gli impartiamo.
Vediamo come sostituire una parola:
echo "giorno" | sed 's/giorno/notte/'
echo "giorno 2" | sed 's/giorno/notte/'
echo "buon giorno" | sed 's/giorno/notte/'
echo "sunday" | sed 's/day/night/'Le espressioni regolari servono proprio per identificare esattamente la parola in modo da evitare, per esempio, che nel caso sia contenuta in altre parole si eviti di sostituirla. Proseguiamo con gli esempi:
echo "buon giorno giorno" | sed 's/giorno/notte/'Il comando che precede sostituisce solamente la prima occorrenza di ‘giorno’. sed infatti lavora i file riga dopo riga ed alla prima occorrenza fa la sostituzione e passa alla riga successiva.
Quindi quando ci sono più occorrenze sulla stessa riga non effettua la sostituzione dalla seconda occorrenza a meno che non venga istruito per farlo “globalmente” aggiungendo il carattere g= alla fine dell’espressione:
echo "buon giorno giorno" | sed 's/giorno/notte/g'Il comando =sed= ha quindi una sintassi strutturata come segue:
(comando)/<stringa-da-cercare>/<stringa-da-sostituire>/(parametri)
Naturalmente posso lavorare con i file da redirigere nello standard input di sed:
sed 's/one/ONE/' < <file> # sostituisce solamente la prima ricorrenza di ogni riga e visualizza il file con le sostituzioni effettuatelezione 3: SED | i separatori, scrivere file
Per utilizzare nelle stringhe di ricerca o sostituzione il carattere separatore delle direcotry in linux (/) devo farlo precedere dal simbolo di ’escape’ (\) altrimenti sed lo interpreterebbe come parte del comando che gli abbiamo impartito.
Ipotizzando di voler cambiare il percorso /usr/bin/bash con /usr/bin/sh all’interno di un file denominato =percorsi=:
sed 's/\/usr\/bin\/bash/\/usr\/bin\/sh/' < percorsiQuando ci sono queste situazioni (la riga diventa difficilmente leggibile ed anche di difficile scrittura), all’interno del comando impartito a sed, in sostituzione del separatore / posso utilizzare altri caratteri come : oppure | come segue:
sed 's:/usr/bin/bash:/usr/bin/sh:' < percorsi
sed 's|/usr/bin/bash|/usr/bin/sh|' < percorsiSe voglio salvare il risultato in un ’nuovo-file’ posso redigere anche l’output di sed:
sed 's:/usr/bin/bash:/usr/bin/sh:' < percorsi > nuovo-filelezione 4: SED | aggiungere apici o parentesi
echo "ciao mamma" | sed s/'[a-z]*/(&)/g'L’espressione che precede mette tra parentesi tonde tutte le occorrenze incontrate:
- le occorrenze sono tutte le sequenze di lettere minuscole;
- il simbolo =&= nella parte relativa alla sostituzione riprende l’occorrenza trovata.
Per abilitare le espressioni regolari estese in sed devo usare il parametro -r:
echo "Ciao mamma" | sed 's/[a-z]*/(&)/g'
echo " Ciao mamma" | sed 's/[a-z]*/(&)/g'
echo "Ciao mamma" | sed -r 's/[a-z]+/(&)/g'
echo "Ciao mamma" | sed -r 's/([a-z]|[A-Z])+/(&)/g'Posso quindi utilizzare il simbolo + (una o più ricorrenze in quanto il simbolo =*= indica zero o più ricorrenze).
Le parentesi tonde possono essere utilizzate lo stesso anche senza l’abilitazione delle espressioni regolari estese ma devo farne l’escape: \( e \).
lezione 5: SED | duplicare una parola
Allo stesso modo l’utilizzo delle espressioni regolari estese mi è utile per la duplicazione di una parola:
echo "123 abc" | sed 's/[0-9]*/& &/'
echo " 123 abc" | sed 's/[0-9]*/& &/'
echo " 123 abc" | sed -r 's/[0-9]+/& &/'lezione 6: SED | invertire parole; le espressioni regoleri
L’utilizzo delle parentesi, come detto in precedenza, crea un pattern identificato da sed con un numero progressivo (da 1 per il primo pattern definito fino a 9 massimo) che viene richiamato nella parte della sostituzione con il numero preceduto dal simbolo di escape \:
echo "123abc" | sed -r 's/([0-9]+)([a-z]+)/\2\1/'
echo "123abc" | sed -r 's/([0-9]+)([a-z]+)/\2 \1/'
echo "123 abc" | sed -r 's/([0-9]+)([a-z]+)/\2\1/'
echo "123 abc" | sed -r 's/([0-9]+)|([a-z]+)/\2@ \1/'
echo "123abc" | sed -r 's/([0-9]+)([a-z]+)/\2@\1/'
echo "123 abc" | sed -r 's/([0-9]+)([a-z]+)/\2@\1/g'
echo "123abc" | sed -r 's/([0-9]+)([a-z]+)/\2@\1/g'lezione 7: SED | eliminare numeri o testo o cambiarne l’ordine
Tramite l’utilizzo dei pattern e delle espressioni regolari estese posso eliminare numeri, testo o cambiarne l’ordine (come visto nella lezione precedente):
echo "abc123" | sed -r 's/([a-z]+).*/\1/'
echo "abc123" | sed -r 's/([a-z]+)(.*)/\2 \1/'
echo "abc123" | sed -r 's/([a-z]+)(.*)/\2/'lezione 8: SED | eliminare parole duplicate
Il riferimento al =pattern= può anche essere inserito nella stringa di ricerca, ad esempio per trovare le parole doppie (inteso come due parole identiche separate da uno spazio) ed eliminarne una:
echo "ciao ciao" | sed -r 's/([a-z]+) \1/\1/'LEZIONE DEL CORSO
Strumento per il debug delle espressioni regolari al seguente LINK: https://regex101.com .
sed -n '1,5 p' <file> # stampa le righe da 1 a 5 sopprimendo l'output del file intero (opzione '-n')
sed -n '5,$ p' <file> # come sopra ma dalla riga 5 alla fine del file
sed -i .$(date +%F) '/^#/d;' <file> # l'opzione '-i' modifica direttamente 'file' e se, come nel caso esposto, viene aggiunta un'estensione, viene creata una copia del file appena lavorato103.2 - zcat, bzcat, xzcat
Per visualizzare file di testo compressi non è necessario decomprimerli ma, a seconda del tipo di compressione, possiamo utilizzare il relativo comando che si comporterà esattamente come cat ma visualizzerà il contenuto del file compresso (utile ad esempio per visualizzare il contenuto dei file nella directory /var/log):
- zcat, visualizza file in formato *.gz;
- bzcat, visualizza file in formato *.bz2;
- xcat, visualizza file in formato *.xz.
103.2 - md5sum, sha256sum, sha512sum
Per calcolare l’integrità di un file possiamo vedere se corrisponde il suo hash che è una rappresentazione alfanumerica di un file calcolata tramite un algoritmo. Possiamo avere diversi modi per calcolare hash di un file:
md5sum <nome-file>
sha256sum <nome-file>
sha512sum <nome-file>103.3 - Copiare, spostare, creare, rinominare file da shell
Il comando touch aggiorna la data dei dati di accesso di un file ed è generalmente utilizzato per creare dei file vuoti:
touch file{1,2,3} # crea 'file1', 'file2' e 'file3'
touch file{1...3} # come il comando precedenteIl comando mv serve a spostare e rinominare i files.
Il comando mkdir serve a creare una o più directory:
mkdir dir{1,2,3} # crea 3 directory come visto sopra per 'touch'
mkdir dir{1...3} # come sopra
mkdir -m 777 <directory> # imposta i permessi della cartella che stiamo creando
mkdir -p dir1/dir2 # crea le cartelle che mancano nel percorso
rmdir <dir> # elimina una directory solo se vuotaumask definisce i permessi predefiniti che vengono utilizzati quando si crea un file o una directory.
Il comando ls elenca i file presenti in una cartella:
ls -lah # (l)ong listing, (a)all e (h)uman readable
ls -lhad <dir> # il parametro '-d' permetti di elencare solo la directory altrimenti ci elencherebbe il contenuto della stessaIn Linux non è possibile creare un file con lo stesso nome di una directory perché le directory sono particolari tipi di file ma sono comunque file.
Il comando rm permette di cancellare file e, con il parametro -r anche directory:
rm -r <dir> # elimina la directory e tutto il suo contenuto
rm -rf <qualcosa> # non chiede forzature ed elimina ricorsivamente (usare solo in caso di necessità)Il comando cp serve a copiare un file da un posto ad un altro e, contemporaneamente se necessario, anche a rinominarlo:
cp <file1> <file2> # in caso 'file2' esistesse già lo sovrascrive senza avvisare
cp -i <file1> <file2> # (i)nteractive, avvisa prima di sovrascrivere
cp -ra <espressione> <destinazione> # copia ricorsivamente (cercando anche di mantenere i permessi) tutto, non segue i link simbolici e non fornisce grandi informazioni in caso di fallimento
cp -ral <espressione> <destinazione> # come il precedente ma segue anche i link simbolici103.3 - archiviazione e compressione di file e cartelle
Compressione
Riduce le dimensioni di un file eliminando l’origine.
Compressione con gzip:
gzip <file> # trasforma nel formato compresso 'file.gz' ed elimina 'file'
gzip -l <file.gz> # mostra informazioni sulla compressione
gunzip <file.gz> # decomprime 'file' ed elimina 'file.gz'
zcat <file.gz> # permette di leggere file di testo compressi con 'gzip'
gzip --help # per vedere i vari parametriCompressione con xz (miglior algoritmo):
xz -z <file> # comprime il file in 'file.xz' eliminando 'file'
xz -l <file.xz> # mostra informazioni sulla compressione
xz -d <file.xz> # per decomprimere (elimina il file compresso)I comandi gzip e xz fa solo compressione, non archiviazione.
Archiviazione
Crea un file che contiene altri file, cartelle e sottocartelle non eliminando gli elementi originali oggetto di archiviazione.
Per l’archiviazione usiamo il comando tar che invece crea un archivio partendo da una moltitudine di file, cartelle e sottocartelle. Lo stesso comando permette anche di comprimere contestualmente il file che stiamo creando utilizzando uno dei vari strumenti di compressione visti:
tar -cvzf <archivio.gz> <cartella/espressione> # (c)reate (v)erbose (z)tipo-compressione (f)ile-name seguito dall'identificazione dei file da archiviare (se indicata una cartella la archivia/comprime con il suo contenuto)
tar -cvf <archivio.tar> <cartella/espressione> # crea solamente l'archivio senza eseguire nessuna compressione che posso eseguire separatamente
tar -xvf <file.compresso> -C <cartella-destinzaione> # se ometto la destinazione decomprime nella cartella correnteAlcune opzioni di =tar=:
-c, crea archivio;-A, aggiunge un ‘file1.tar’ ad un altro ‘file.tar’;-r, aggiunge ad un ‘file.tar’ dei file normali (non archivi);-u, inserisce nell’archivio una versione aggiornate di un ‘file’;-d, compara l’archivio con i file presenti su disco;-t, lista i contenuti;-x, estrae l’archivio;-v, modalità verbosa;-f, indica il nome del file da creare o decomprimere;-J, comprime con xz;-z, comprime con gzip.
103.3 - rpm, cpio, rpm2cpio, yumdownloader
cpio è un formato di archiviazione standard in linux ancora largamente utilizzato nei pacchetti rmp (RedHat/Fedora/CentOS e derivate).
yum install <pacchetto> # installa il pacchetto .rpm e tutte le sue dipendenze
yumdownloader <pacchetto> # fa solamente il download del pacchetto .rpm
yumdownloader --resolve <pacchetto> # scarica anche le dipendenze per poter (ad esempio) installare il pacchetto e tutte le dipendenze quando siamo offline
rpm2cpio <pacchetto.rpm> > <pacchetto.cpio> # estrae da un pacchetto .rpm il relativo archivio in formato .cpio
cpio -id < <archivio.cpio> # estrae (-i) il contenuto dell'archivio nella directory corrente creando, se necessario, le relative directory (-d)
cpio -t < <archivio.cpio> # mostra il contenuto di un archivio .cpio
rpm2cpio <pacchetto.rpm> | cpio -t # mostra il contenuto del pacchetto .rpm
ls <files-da-archiviare> | cpio -ov > archivio.cpio # crea (-o) un archivio .cpio in modalità verbosa (-v)103.3 - Il leggendario comando dd
premessa : le dimensioni per i calcolatori
I computer ragionano in modalità binaria:
- 1 bit può assumere solo due valori : 0|1;
- 1 byte è una sequenza di 8 bits e può rappresentare 0-255 caratteri;
- 1 kilobyte = 2^10 bytes = 1.024 bytes;
- 1 megabyte = 2^20 bytes = 1.024x1.024 = 1.048.576 bytes;
- 1 gigabyte = 2^30 bytes = 1.024x1.024x1.024 = 1.073.741.824 bytes.
Simbologia:
- 1K = 1.024 bytes;
- 1KB = 1.000 bytes;
- 1M = 1.024K;
- 1MB = 1.000K;
- 1G = 1.024M;
- 1GB =1.000M.
Block Size (bs) : i filesystem generalmente scrivono su disco a blocchi di 4K (4.096 bytes).
Questo significa che, anche se il mio file è di dimensione inferiore, occuperà lo spazio minimo del blocco andando a “sprecare” spazio su disco. Questo però avviene per diminuire il numeri di volte che viene effettuata la scrittura su disco in quanto file di piccole dimensioni sono sempre più rari e più cicli di scrittura significa un utilizzo maggiore della risorsa più preziosa, ovvero la CPU.
Facciamo un esempio, devo scrivere su disco 2 file:
- 1 file di 1K;
- 1 file di 10M (1.024K).
Lo posso fare su 2 filesystem diversi:
- il primo scrive a blocchi di 4K;
- il secondo a blocchi di 1K.
Sul primo filesystem i 2 files occuperanno uno spazio di 1.028K (4K per il file di 1K e 1.024K per il file di 1M) “sprecando” spazio su disco per 3K mentre sul secondo =filesystem= occuperò 1.025K, esattamente lo spazio necessario ai file in quanto il block-size è proprio di 1K pari al file più piccolo.
Tutto comporta che il primo filesystem necessiterà di 257 cicli di scrittura da 4K ciascuno (la dimensione del bs) mentre il secondo 1.025K cicli. Quindi la scelta è tra spreco di spazio (residuale all’effettiva grandezza dei singoli file) e spreco di risorse (CPU).
La dimensione minima del Block Size è pari a 512 bytes.
LEZIONE : Il leggendario comando dd
Alcune funzioni del comando dd sono:
- fare dump di intere partizioni in un file e viceversa;
- clonare dischi e partizioni;
- creare immagine .iso di partizioni e dischi;
- convertire file di testo da uppercase a lowercase e viceversa;
- sovrascrivere file con zeri o caratteri casuali per eliminarli in sicurezza;
- fare backup del MBR di un disco;
- misurare le prestazioni in scrittura di un disco.
Vediamo solamente alcuni esempi:
dd if=<text-lowercase> of=<text-uppercase> conv=ucase # tutto maiuscolo
dd if=<text-uppercase> of=<text-lowercase> conv=lcase # tutto minuscolo
dd if=/dev/zero of=<new-file> bs=1024 count=1 # crea un file di 1 KB (anche se la dimensione occupata su disco sarà 4kb perchè il filesystem legge blocchi minimi di tali dimensione)
dd if=/dev/zero of=<new-file> bs=4096 count=1 # crea un file di 4 KB (che occuperanno per intero lo spazio che il filesystem ha riservato al file su disco a differenza del comando precedente)
dd if=/dev/zero of=<new-file> bs=4K count=1 # crea un file di 4KB
dd if=/dev/zero of=<new-file> bs=1M count=1 # crea un file di 1.024KBEliminazione sicura di un file (in quanto rm elimina solo l’indice del file e non effettivamente il file).
Il metodo è sovrascrivere il file con dati casuali in modo da cancellare tutto quanto conteneva e poi eliminarlo con rm:
dd if=/dev/urandom of=<file-da-eliminare> bs=<dimensione> count=1
rm <file-da-eliminare>103.3 - find, locate, updatedb
Il comando locate indicizza i file presenti sul disco in un database e permette una ricerca veloce quando stiamo cercando qualcosa:
locate <nome-file-o-cartella> # cerca file o cartelle
sudo updatedb # aggiorna il dbIl problema di locate è che il db viene aggiornato periodicamente e pertanto potrebbe trovare un file che è appena stato eliminato o non trovare un file che è appena stato creato.
Il comando che effettua ricerche in tempo reale è find:
find <percorso> -name <nome> # ricerca case sensitive
find <percorso> -iname <nome> # case insensitive
find <percorso> -iname <espressione> # cerca file e cartelle tramite espressione
find <percorso> -name <nome> 2>/dev/null # sopprime gli errori (tipo permesso negato)
find <percorso> -iname <nome> -exec ls -lhd {} \; # esegue un comando (anche 'rm') su ogni singolo risultato della ricercaSpiegazione del parametro -exec ls -lhd {} \;.
Viene eseguita una concatenazione di comandi bash inserendo tra le parentesi graffe ogni singolo risultato della ricerca, infatti l’espressione finisce con ; (che è un carattere che deve essere preceduto dal carattere escape \).
Altri esempi di utilizzo del comando find:
find <percorso> -iname <file> -type f # cerca solo i file
find <percorso> -iname <file> -type d # cerca solo le cartelle
find <percorso> -maxdepth 1 -iname <file> # specifica la profondità massima in cui cercare in termini numeri di cartelle all'interno del percorso
find <percorso> -iname '*' -mtime +365 -exec ls -lhdt {} \; # cerca file più vecchi di 365 giorni
find <percorso> -iname '*' -mtime -30 -exec ls -lhdt {} \; # cerca file creati/modificati negli ultimi 30 giorni
find <percorso> -iname '*' -size +4k # cerca file di dimensione maggiore di 4 kilobytes
find <percorso> -iname '*' -size -4M # cerca file di dimensione minore di 4 Mega103.3 - bunzip2, unxz
Le estensioni .bz2 e .xz caratterizzano file compressi che utilizzano i seguenti 2 comandi per estrarre il file che è stato appunto compresso in precedenza:
bunzip2 <file.bz2>
unxz <file.xz>103.4 - streams, redirection e pipe
I simboli di redirezione in Linux sono:
>oppure1>, standard output;>>, standard output append;2>, standard error;<, standard input;<<<, here string.
Vediamo come può essere gestito il flusso output di un comando che si divide tra standard output e standard error:
&>, redirige tutto, sia standard output e standard error;2>&1, redirige lo standard error all’interno del flusso di standard output;1>&2, redirige lo standard output all’interno del flusso di standard error.
L’opzione noclobber della shell bash impedisce la sovrascrittura di un file esistente in caso di redirezione dello standard output (che non sia tramite >> chiaramente) generando un errore:
set -o noclobber # attiva l'opzione
set +o noclobber # disattiva l'opzione
set -o # visualizza tutte le opzioni di bash, sia attive che non attiveLa pipe dopo il simbolo di redirezione dell’output (i.e. |) forza la sovrascrittura del file esistente anche se è attiva l’opzione noclobber.
Il comando tee riceve lo standard input da una pipe e fa 2 cose:
- lo stampa a video;
- e lo scrive su un file indicato come parametro.
Esempio di pipe:
ls -l | sort -k9 -r # ordine alfabetico inverso della colonna 9 (quella del nome)Il comando xargs prende in ingresso una serie di elementi separati da spazi, \newline ed il carattere di tabulazione e li utilizza uno alla volta oppure più alla volta a seconda del parametro -n (di default li utilizza tutti insieme) a loro volta come parametro al comando che segue, vediamo degli esempi:
echo {1..9} | xargs
echo {1..9} | xargs -n1
echo {1..9} | xargs -n3
echo "1 2 3" | xargs -n1 echo "N"
echo "1 2 3" | xargs echo "N"
find <percorso> -iname 'espressione' | xargs tar -czvf <archivio.tar.gz>Redirezione standard input:
cat <file> | sort | <elenco> # ordina gli elementi di 'file' e liscrive in 'elenco'
sort < <file> > <elenco> # fa la stessa cosa del comando precedente senza pipe
sort < <file> | <elenco> # fa sempre la stessa cosaIl simbolo di redirezione <<< (here strings) non fa altro che redirigere allo standard input del comando che precede tutto quanto come stringa di testo e non come file:
echo "1 2 3" | xargs -n1 # elenca gli argomenti andando a capo uno alla volta
xargs -n1 <<< "1 2 3" # stesso risultato come sopra
cat <<< "prova" # visualizza la stringa "prova"
cat < "prova" # visualizza il contenuto del file 'prova'103.5 - I jobs in Linux
Quando un comando tiene impegnata la shell per un certo tempo posso premere:
C-c, per interrompe il processo legato al comando;C-z, per stoppare il processo legato al comando ed assegnarli un numero di job progressivo (partendo da 1)
A questo punto i seguenti comandi:
jobs # elenca i jobs che sta gestendo la shell con l'informazione (tra le altre) del loro stato (ossia in esecuzione o stoppato)
bg 1 # in caso di presenza di un processo in stato stoppato posso proseguirlo lasciandolo in background
fg 1 # oppure posso proseguirlo riportandolo in foreground (dopo 'bg' ed 'fg' metto il numero di job)Posso anche decidere di lanciare un comando e metterlo subito in esecuzione in background aggiungendo il simbolo & alla fine della riga di comando.
Occorre anche tenere presente che, se non redirigo gli standard output ed error dei comandi che metto in background, questi continueranno ad essere visualizzati nella shell corrente dando comunque fastidio.
E’ pertanto consigliabile redirigerli in qualche file oppure verso /dev/null quando si mette in background un comando.
103.5 - Eseguire processi con nohup
Se voglio eseguire un comando che necessiterà di molto tempo per terminare la sua esecuzione, e che quindi dovrà continuare anche quando io mi sconnetterò dalla shell o dal sistema, posso utilizzare il comando nohup:
nohup <comando> &Questo redirige standard output e standard error ad un file dal nome nohup.out in modo che quando tornerò ad accedere alla macchina potrà verificare quanto il comando avrebbe mostrato durante la sua esecuzione se fossi rimando connesso con la shell aperta ed il job in primo piano.
103.5 - top, free, uptime
Il comando top mostra parecchie informazioni sul sistema e sui processi in esecuzione. Lanciando il comando senza nessun parametro permette di eseguirlo in modo interattivo. In questa modalità posso interagire (appunto) tramite la pressione di tasti:
l, abilita disabilita i dati sull’uptime;m, abilita disabilita le informazioni sulla memoria passando dalla visualizzazione come grafico (non in tutte le versioni di top);t, come per la memoria la pressione ditvale per le informazioni sulla CPU;F, entra nelle impostazioni di Fields Management.
All’interno di Field Management posso premere:
doppureSPACE, aggiunge/toglie la colonna da visualizzare;s, su una determinata colonna stabilisce che l’ordinamento dei processi debba essere fatto in base a quella colonna;ENTER, torna alla visualizzazione interattiva di top salvando le modifiche.
Per invertire l’ordinamento predefinito basta premere il tasto R quando siamo in modalità interattiva e stiamo visualizzando tutti i processi.
Il comando top può anche essere eseguito in batch ossia in modalità non interattiva tramite l’utilizzo del parametro -b:
top -b -n2 -d5 # esegue 'top' 2 volte a distanza di 5 secondiVediamo questi ultimi 2 comandi che forniscono alcune informazioni che troviamo all’interno di top:
uptime # restituisce la prima riga di top
free -m # restituisce le stesse informazioni di top riguardo l'utilizzo della memoria103.5 - ps, pgrep, pkill, killall
Il comando ps restituisce l’elenco dei processi della bash corrente:
ps # tipicamente restituisce 2 processi, ossia 'bash' (la shell) ed il comando 'ps' appena lanciato
ps -f # restituisce alcune informazioni in più compreso il 'parent pid' che sarà presumibilmente sempre bash
ps -lf # restituisce un elenco ancora più dettagliato
ps -e # restituisce l'elenco di tutti i processi in esecuzione
ps -u <nome-utente> # restituisce tutti processi che appartengono a 'nome-utente'Notazione sul valore di nice, esso può assumere valori da -20 a +19:
- -20, significa che il processo è “poco gentile” (nice) e si prende molto tempo della CPU;
- +19, significa che il processo è gentile e si prende poco tempo della CPU lasciandone maggiormente agli altri processi
Vediamo ora il comando pgrep:
pgrep <nome-processo> # restituisce il pid dei processi che contengono 'nome-processo'
ps -e | grep <nome-processo> # restituisce gli stessi processi del comando precedenteI processi si possono terminare/uccidere con vari comandi che ruotano attorno al comando kill.
Lanciandolo con l’opzione -l viene elencato il numero di segnale che si può utilizzare tra cui:
1SIGHUP, che forza il reload del processo;15SIGTERM, che termina il processo in modo regolare (parametro di default);9SIGKILL, che uccide il processo brutalmente (si usa generalmente se non funziona il precedente).
Vediamo ancora qualche esempio:
kill <numero-pid> # chiede al processo di terminarsi utilizzando il codice 15 (default)
kill -s -9 <numero-pid> # uccide il processo (codice -9)
pkill <nome-processo> # termina tutti i processi che contengono 'nome-processo' nel loro nome (pericoloso)
killall <nome-processo> # come il precedente ma richiede il nome esatto del processo
killall -s 9 -u <nome-utente> <nome-processo> # uccide tutti i processi che si chiamano 'nome-processo' e che appartengono all'utente 'nome-utente'103.5 - La cartella /proc
La cartella /proc/ è un filesystem virtuale per i processi.
All’interno di questa cartella troviamo, tra le altre cose, tante sottocartelle quanti sono i processi in esecuzione il cui nome corrisponde al numero di pid del processo. In ognuna di queste sottocartelle vi sono molte informazioni utili che riguardano il relativo processo.
Tutte le varie applicazioni di monitoraggio dei processi (come ad esempio top) attingono a queste cartelle per esporre le varie informazioni sui processi attivi.
103.5 - watch : tenere monitorati i comandi
Il comando watch è una utility che esegue periodicamente (default 2 secondi) un altro comando che viene fornito come parametro, vediamo un paio di esempi:
watch -n 1 ls -lh /var/log # esegue il comando 'ls' ad intervalli di 1 secondo
watch -n 1 ping -c 1 google.com # esegue 1 ping a google ogni secondo103.5 - tmux moltiplicatore di terminali
Il comando tmux aggira i limiti che si hanno generalmente quando ci si collega tramite ssh o quando si utilizza un terminale a caratteri dove si deve gestire tutto da una sola finestra. Inoltre permette anche di gestire delle sessioni di lavoro che possono essere lasciate attive nella macchina anche dopo il nostro logout fino al successivo collegamento.
All’avvio di tmux vediamo una barra in basso che gestisce le nostre varie shell.
L’interazione con il programma avviene tramite la combinazione C-b seguita dal carattere che identifica il comando che vogliamo eseguire, vediamo i principali:
c, crea una nuova shell bash (o finestra);,, rinomina la finestra corrente (contrassegnata con*)p, si sposta alla finestra precedente - (p)revious;n, si sposta alla finestra successiva - (n)ext;w, crea un elenco delle finestre dove si può selezionare quella dove ci si vuole spostare;%, splitta verticalmente la finestra corrente;", splitta orizzontalmente la finestra corrente;Up/Down/Left/Right, si muove tra le varie shell create nella finestra corrente;d, si scollega dalla sessione sessione corrente lasciandola attiva sulla macchina - (d)detached;C-d, non preceduta daC-bequivale a uscire dalle varie shell con exit.
Dopo essersi scollegati con d la sessione rimane attiva sulla macchina anche se ci scolleghiamo dalla macchina stessa.
Una volta che torniamo ad effettuare il login ci possiamo ricollegare:
tmux ls # elenca le sessioni attive sulla macchina
tmux attach -t <nome sessione> # si collega ad una sessioneUna nuova sessione può essere creata con il semplice comando tmux e gli può essere assegnato un nome tramite il parametro -s:
tmux new -s <nome-sessione>103.6 - nice e renice
Il valore di nice di un processo influenza il suo livello di priority:
ps -l # visualizza l'elenco dei processi della shell comprese le colonne con il valore di nice (NI default 0) ed il valore di priority (PRI default 80)
nice -n 5 <comando> # lancia un comando con valore di nice 5 e priority 85 (aggiunge il valore di nice)
renice -n 7 <PID> # cambia il valore di nice di un processoDa evidenziare com l’utente normale può lanciare comandi con valori di nice da 0 a +19 mentre l’utente root può utilizzare anche valori negativi.
Allo stesso modo l’utente root può variare il valore di nice dei processi in esecuzione senza limitazioni mentre un utente normale può solo aumentarne il valore e non diminuirlo.
Il valore di nice può essere variato anche dal comando top lanciato in modalità interattiva premento il tasto r. Prima viene chiesto il PID del processo sul quale si vuole operare (default quello su cui abbiamo il cursore) e poi il nuovo valore di nice che vogliamo assegnare.
Vediamo ancora un paio di comandi che possono servire per cambiare il valore di nice a più processi contemporaneamente:
renice -n 0 -u <nome-utente> # azzera il valore di nice di tutti i processi lanciari da un determinato utente
renice -n 0 -g <gruppo> # fa la stessa cosa per tutti i processi di un determinato gruppo103.7 - Le espressioni regolari (regex)
grep morro <file> # restituisce tutte le linee che contengono 'morro', case sensitive
grep -i morro <file> # restituisce tutte le linee che contengono 'morro', case insensitive
grep '[Mm]orro' <file> # restituisce le righe che contengono 'Morro' oppure 'morro'
grep '[^L]inux' <file> # restituisce tutte le linee che NON hanno un carattere 'L' seguito da 'inux' (es. 'Sinux', 'tinux', ecc..)
grep -w linux <file> # cerca un parola intera, case sensitive
grep -iw linux <file> # cerca un parola intera, case insensitive
grep '[0-9]' <file> # cerca la ricorrenza di un numero da 0 a 9
grep -E '[0-9]{4}' <file> # cerca 4 numeri 0-9 consecutivi, il parametro '-E' interpreta le espressioni regolari
egrep '[0-9]{4}' <file> # come il precedente ma deprecato
fgrep 'espressione' <file> # cerca esattamente l'espressione senza interpretare simboli quali parentesi quadre o graffe
sed 's/<ricerca>/<sostituzione>/' <file> # sostituisce la prima ricorrenza (vedi il capitolo su 'sed')
sed -i 's/<ricerca>/<sostituzione>/' <file> # modifica direttamente 'file'
sed '/^linux/d' <file> # elimina le righe che iniziano con la parola 'linux'103.8 - introduzione a VI
Spesso vi è un collegamento a vim:
vi 'file' # apre un file esistente o lo creaEsistono 3 diverse modalità in cui si può operare in vi:
i, modalità inserimento / insert mode;:, modalità comando / command mode;ESC, modalità movimento / motion mode.
Nella modalità motion mode la pressione dei tasti esegue delle azioni, iniziamo a vedere come spostarsi con il cursore:
h, a sinistra di un carattere;j, in basso di una riga;k=, in alto di una riga;l, a destra di un carattere;b, all’inizio di ogni parola;w, alla fine di ogni parola;e, alla fine della parola successiva;(, indietro di una frase;), avanti di una frase;{, indietro di un paragrafo;}, avanti di un paragrafo;$, a fine riga;0, ad inizio riga;G, alla fine del file;gg, all’inizio del file.
In vi si può sempre specificare quante volte eseguire un comando premettendo il relativo numero al comando:
5w, avanti di 5 parole;15G, alla riga numero 15;:15, alla riga 15 ma utilizzando command mode.
Copiare e incollare in vi:
yy, copia la riga corrente;p, incolla dopo il cursore (la riga sotto in questo caso);P, incolla prima del cursore (la riga sopra in questo caso);10p, incolla sotto 10 volte.
Vediamo altri comandi da utilizzare in motion mode:
dd, cancella l’intera riga dove si trova il cursore;8dd, elimina 8 righe in successione compresa quella dove si trova il cursore;u, annulla (undo) in successione comandi o digitazioni;C+r, ripete l’azione annullata (redo);x, elimina il carattere sotto al cursore (come il tastoDEL);X, elimina il carattere precedente al cursore (come il tastoBACKSPACE);D, elimina dal cursore a fine riga.
Cercare del testo con vi:
/, cerca la prima occorrenza digitata;n, cerca il risultato successivo della ricerca in avanti nel file;N, cerca il risultato precedente della ricerca nel file;?, cerca a ritroso la prima occorrenza digitata (invertendo l’utilizzo dei comandineN);n, continua a cerca all’indietro;N, continua a cerca in avanti.
Alcuni comandi invece da digitare in command mode:
:w, salva il file;:wq, salva il file ed esce da vi;:q, esce da vi;:q!, forza l’uscita da vi anche se il file è stato modificato.
Alcuni modi per entrare in insert mode:
i, entra in insert mode;o, crea una riga vuota sotto ed entra in insert mode;O, crea una riga sopra ed entra in insert mode;A, va a fine riga ed entra in insert mode - (a)ppend;s, elimina il carattere dove si trova il cursore ed entra in insert mode;R, entra in modalità sostituzione sovrascrivendo i caratteri successivi (come entrare in insert mode e premereINS).
Cercare e sostituire testo (molto simile a sed):
:s/<parola>/<sostituto>, sostituisce la prima occorrenza nella riga corrente;:s/<parola>/<sostituto>/g, sostituisce tutte le occorrenze nella riga corrente;:%s/<parola>/<sostituto>/, sostituisce la prima occorrenza trovata in tutte le righe del file;:%s/<parola>/<sostituto>/g, sostituisce tutte le occorrenza trovate nell’intero file;:%s/<parola>/<sostituto>/gc, come il precedente ma chiede (c)onferma ad ogni sostituzione;r, sostituisce il carattere sotto al cursore con il successivo carattere premuto.
103.8 - Default EDITOR e nano
In Linux esistono altri editor di testo oltre a vi, ad esempio:
nano;emacs;ed.
Possiamo impostare l’editor di testo predefinito:
- modificando il link simbolico
/etc/alternatives/editor; - modificando la variabile $EDITOR con il percorso del comando del nostro editor preferito.
Test pratico 2 : Test sul capitolo 103
Lezioni da n. 39 a n. 75.
Risposte giuste: 21 su 23.
Riassunto comandi più comuni
alias e type
type <comando> # distingue il comando tra alias, shell builtin, o percorso dell'eseguibile
alias abbreviazione='<comando-completo>' # crea un alias per digitare 'abbreviazione' anziché 'comando-completo'shell history
history # mostra i comandi digitati in precedenza
history -c # pulisce la cronologia dei comandi
C-r # inizia la ricerca nella history
!! # esegue nuovamente l'ultimo comando invocato
!$ # richiama il parametro usato nell'ultimo comando invocatomanuale
man <comando> # apre il manuale utente per il comando specificato (il manuale utente non è presente per i comandi shell builtin)
<comando> --help # mostra l'help per il programma specificato (solitamente più sintetico del man, presente anche per i builtin)informazioni sul sistema
uname -a # mostra tutte le info sul kernel in esecuzione
uname -r # mostra solo il numero di versione del kernellavorare con i file di testo
Premessa: l’operatore > ha sempre il compito di redirigere l’output (stdout) sul file indicato:
split -l 100 file.txt # divide file.txt in 'n' file da 100 righe ciascuno
split -b 5m video.mp4 # divide video.mp4 (file binario, non di testo!) in porzioni di 5mb
cat video* > unito.mp4 # unisce nuovamente tutti i file con prefisso nominale 'video' nel file unito.mp4 (funziona con qualunque formato)
cut -d ':' -f 1 ab.txt # imposta come separatore di colonna il carattere ':' e stampa la prima colonna
cut -d ':' -f1,7 ab.txt # come sopra, ma stampa le colonne da 1 a 7
head -n 10 file.txt # mostra solo le prime 10 righe di file.txt
tail -n 10 file.txt # mostra solo le ultime 10 righe di file.txt
wc -l file.txt # conta il numero di righe presenti in file.txt
wc -c file.txt # conta il numero di caratteri presenti in file.txt
less file.txt # visualizza file.txt poco per volta. usare le frecce per navigare il documento (Up/Down)
zcat file.txt.gz # visualizza file.txt.gz (compresso) senza bisogno di decomprimerlo
bzcat file.txt.bz2 # come sopra, per i file compressi in formato .bz2
xzcat file.txt.xz # come sopra, per i file compressi in formato .xzgestione dei file
pwd # mostra il percorso della cartella in cui ci troviamo (directory locale)
ls # mostra il contenuto della cartella in cui ci troviamo (directory locale)
cd Scrivania # ci spostiamo con il terminale nella cartella chiamata 'Scrivania' (deve esistere, con quel nome, nella directory locale)
du -sh folder # restituisce la dimensione della cartella 'folder', comprensiva di tutti i file in essa contenuti
md5sum file # calcola la somma md5 per 'file', può essere utile se confrontato con un una copia del file sicuramente integra
cp file.txt new.txt # crea una copia di 'file.txt' chiamata 'new.txt'
cp -r cart1 cart2 # crea una copia della cartella 'cart1' (e ricorsivamente il suo contenuto) chiamata 'cart2'
mv old new # rinomina il file 'old' come 'new'
mv old Desktop/new # sposta il file 'old' sul 'Desktop', con il nome cambiato in 'new'
rm file.txt # elimina 'file.txt'
rm -r folder # elimina la cartella 'folder' ed il suo contenuto (utilizzare anche il parametro '-f' per rimuovere forzatamente)
mkdir folder # crea la cartella 'folder'
mkdir -p folder/ciao # crea la cartella 'folder' e al suo interno la sottocartella 'ciao' con un unico comando
gzip file # genera un file compresso chiamato 'file.gz' ELIMINANDO il file originale
gunzip file.gz # estrae 'file.gz' ELIMINANDO la sua verisone compressa con estensione .gz
tar -czf var.tar.gz var # comprime la cartella 'var' in un archivio chiamato 'var.tar.gz'
tar -xzf var.tar.gz # estrae nella cartella locale il contenuto dell'archivio 'var.tar.gz'
dd if=/file of=new # copia bit a bit il contenuto di 'file' in 'new', spesso usato per clonare supporti di memorizzazione di massa
find / -iname "ciao" # cerca su tutto il filesystem i file chiamati 'ciao' senza distinguere tra maiuscole e minuscole ('-iname')streams, redireciton e pipes
ls > out.txt # redirige l'output di 'ls' nel file 'out.txt'
ls 2> err.txt # redirige eventuali errori di 'ls' nel file 'err.txt'
ls &> out.txt # redirige errori e output di 'ls' nel file 'out.txt'
cat < in.txt # redirige l'input di 'cat' per leggere 'in.txt' (ma non è necessario usare l'operatore di redirezione con 'cat')
cat in.txt # stesso effetto del comando precedente
prog1 | prog2 # redirige l'output del programma 'prog1' sull'input di 'prog2'gestione processi e risorse
C-z # manda un processo in background (ed in pausa)
jobs # mostra i processi in background
fg <n> # riporta in foreground (in primo piano) il processo 'n'
ps aux # mostra tutti i processi in esecuzione sulla macchina
top # mostra in maniera interattiva tutti i processi in esecuzione, compreso utilizzo delle risorse (stile task manager)
htop # versione più evoluta di 'top'
free -m # mostra l'uso di memoria RAM
df -h # mostra l'uso del disco (spazio libero per ogni partizione)
iotop # (extra) mostra l'uso del disco (letture/scritture correnti, e da quali processi)
nohup <cmd> # esegue il comando 'cmd' in modo che non venga interrotto quando chiudiamo la shell o ci scolleghiamo
kill [-S] <pid> # uccide il processo con un dato 'pid' (il parametro '-S' specifica il codice di terminazione come, ad esempio, -15 o -9)
killall <nome> # uccide tutti i processi con un certo nomeSezione 5 : 104 - Dispositivi, Filesystem Linux, Filesystem Hierarchy Standard
104.1 - MBR vs GPT
MBR (Master Boot Record), è stato introdotto da IBM nel 1983 ed è caratterizzato dal fatto che i primi 512 bytes del disco contengono il bootloader. Pertanto il BIOS non deve fare altro che leggerli per dare inizio all’avvio della macchina.
MBR ha delle limitazioni quali:
- funziona solo con dischi di max 2TB;
- supporta al massimo 4 partizioni primarie.
GPT (GUID Partition Table) è stato progettato da Intel a fine anni 90 ed introdotto intorno al 2010, vediamo alcune caratteristiche e differenze con MBR:
- ogni partizione ha un identificatore univoco (GUID - Global Unique IDentifier);
- supporta fino a 128 partizioni primarie;
- a differenza di MBR, le informazioni sullo schema della partizioni sono salvate in più settori del disco, quindi migliore resistenza alle corruzioni del disco;
- tramite i CRC (Cyclic Redundancy Check), GPT può controllare l’integrità dei dati e tentare la riparazione.
GPT si è diffuso insieme a UEFI, il nuovo standard di boot che prevede la presenza di una partizione UEFI (Fat32) di qualche centinaio di MB che contiene il bootloader e sostituisce i primi settori del disco, tipici di MBR.
Per formattare un disco usando MBR o GPT posso usare il comando =parted=:
parted /dev/sdb
(parted) mklabel104.1 - FAT32 vs exFAT ; Btrfs
FAT32 (32 Bit File Allocation Table)
E’ sicuramente il filesystem più diffuso perchè compatibile trasversalmente con Windows, MacOS e Linux, ha però forti limitazioni quali:
- supporto di una dimensione massima per un file di 4GB;
- è un filesystem molto soggetto a frammentazione.
exFAT
Introdotto più recentemente, risolve queste limitazioni mantenendo la compatibilità multipiattaforma:
- dimensione massima per un file pari a 16EB (1 milione di TB);
- migliorate le prestazioni in termini di frammentazione.
Creazione filesystem
Sia nel caso di FAT32 che exFAT, dopo aver creato la partizione tramite =parted=, dovrò provvedere a creare il filesystem. Esempio nel caso di filesystem exFAT:
apt install exfat-fuse # permette di montare e leggere partizioni exFAT
apt install exfat-utils # permette di creare partizioni exFAT
mkfs.exfat 'partizione'Btrfs (B-Tree FileSystem)
Lato Linux abbiamo il filesystem Btrfs che fornisce diverse funzionalità avanzate (ma è ancora in fase di sviluppo) quali:
- supporto nativo per dispositivi multipli;
- compressione nativa zlib;
- sotto-volumi con diverse radici del filesystem;
- supporto nativo agli snapshot;
- conversione in-place (sul posto) da filesystem ext2/3/4.
Soprattutto l’ultima caratteristica permette di passare a Btrfs senza dover formattare il disco se questo è formattato con ext2, ext3 o ext4.
104.2 - Mantenere l’integrità del filesystem
Ad ogni montaggio del filesystem c’è un contatore che viene incrementato e, se è abilitata la funzione di check, viene controllata l’integrità del filesystem ogni X montaggi:
tune2fs -l <partizione> # genera un po' di informazioni tra cui 'Mount count' e 'Maximum mount count' (se questo è impostato a '-1' non viene mai effettuato il check
tune2fs -c 15 <partizione> # imposta il numero di montaggi dopo cui effettuare il check: '-1' significa mai, '1' significa ogni volta che viene montatoNel file /etc/fstab sono elencate le partizioni di cui facciamo il mount in fase di boot, il valore indicato alla sesta colonna (l’ultima) può essere 0 (significa che non è previsto fare il check della partizione) oppure un numero positivo che, oltre a prevedere il check della partizione, ne stabilisce anche l’ordine (1,2,3…).
Il controllo può anche essere lanciato manualmente tramite l’utility fsck che sul sistema è presente con vari comandi a seconda del tipo di filesystem che si vuole controllare e spesso sono presenti link simbolici tra i vari comandi per avere più opzioni di lancio del comando stesso:
e2fsck # per le famiglie 'ext2', 'ext3', 'ext4'
dosfsck # per le famiglie 'fat' (è un link simbolico a 'fsck.fat')
reiserfsck # per i filesystem di tipo 'reiser'
xfs_repair # per filesystem di tipo 'XFS' (necessita del pacchetto 'xfsprogs')Se la partizione è montata in scrittura non è possibile effettuare il check:
mount -o remount,ro <partizione> # rimonta la partizione in sola letturaE’ comunque vivamente sconsigliato fare il check di partizioni montate in sola lettura ma questo può essere forzato tramite:
e2fsck <partizione> -fIl check è consigliato quando la partizione non è montata (infatti avviene al boot).
Vediamo un paio di utilizzi dell’utility fsck:
fsck -A # fa il controllo di tutte le unità che devono essere controllate in base alle impostazioni che sono scritte nel file '/etc/fstab'
fsck -a # esegue la riparazione in automatico senza chiedere confermadebugfs è una shell interattiva per analizzare i filesystem ext2/ext3/ext4 e che, tra le altre cose, permette di mostrare l’inode dove è salvato un file e anche l’inode dove sono scritti i file cancellati di recente per cercare di recuperarli (questa procedura di undelete si è complicata dalla versione ext3 in poi):
debugfs # lancia l'utility in modalità interattiva
debugfs: ? # visualizza l'elenco dei comandi disponibili
debugfs: open <partizione> # 'apre' una partizione
debugfs: pwd # verifica in quale directory siamo
debugfs: cd <cartella> # cambia directory
debugfs: ls # elenca files e directories con i relativi 'inode'
debugfs: ls -d # elenca anche i files e directries (questi ultimi con inode tra '<>')
debugfs: quit # esce dalla shell interattiva di debugfsdumpe2fs è un altro comando che fornisce informazioni sulle partizioni ext2/ext3/ext4:
dumpe2fs -h <partizione> # fornisce informazioni analoghe a 'tune2fs -l'104.3 - Montare e smontare filesystems : mount e umount
mount # mostra tutti i filesystem montati
fdisk -l # mostra i dispositivi fisicamente collegate al computer
parted -l # mostra sostanzialmente le stesse informazioni di 'fdisk -l'
mount <partizione> <punto-di-mount> # monta una partizione
umount <punto-di-mount> # smonta una partizioneIn Linux sono stati dedicati 2 punti di mount:
- /mnt
- /media
Montare una partizione maschera il contenuto della directory su cui è montato, che torna visibile quando smontiamo la partizione.
Montare una partizione con il comando mount inoltre non è un’operazione permanente nel senso che al successivo riavvio questa risulterà ancora non montata.
Per poter rendere permanente ad ogni avvio il montaggio di una partizione dobbiamo modificare il file /etc/fstab.
Il file /etc/fstab è suddiviso in 6 colonne di informazioni:
- file-system, identifica la partizione (meglio tramite UUID);
- mount point, specifica il punto di mount;
- type, precisa la tipologia di filesystem contenuta nella partizione;
- option, elenca le varie opzioni di montaggio;
- dump, viene letto dal comando dump, se pari a
0non necessita del suo intervento; - pass, viene letto dal comando fsck e, se pari a
0non necessita del suo intervento.
Nel primo campo è meglio usare gli UUID invece che il percorso della partizione in quanto, nel caso si dovessero montare più dischi, in fase di boot potrebbe cambiare l’ordine di riconoscimento degli stessi da parte del sistema assegnando una lettera diversa e creando confusione poi in fase di montaggio.
L’utilizzo di UUID non corre questo rischio in quanto è un riferimento univoco:
blkid <partizione> # mostra lo 'UUID' della partizione104.3 - lsblk, blkid, systemd mount units
lsblk # mostra i block-devices o dispositivi di memorizzazione di massa, sia fisici che vistuali
blkid <device> # mostra 'UUID' e 'PARTUUID' della partizione, del disco o del dispositivoVediamo la differenza tra UUID e PARTUUID:
- UUID, ID della partizione assegnato da Linux;
- PARTUUID, ID della partizione assegnato da GPT.
Nel file /etc/fstab posso indicare indifferentemente l’uno o l’altro UUID.
Un metodo alternativo per montare dischi e le partizioni all’avvio è utilizzare systemd tramite la creazione delle mount units.
Per fare un esempio concreto provo a creare una unità che mi faccia il mount di una partizione non montata con /etc/fstab.
Devo creare l’unità al percorso /etc/systemd/system/mnt-part4.mount che indica il montaggio della partizione al percorso /mnt/part4 dove per convenzione - viene interpretato come fosse il separatore delle directory (dovremo chiaramente creare la directory).
[Unit]
Description=Monta la partizione 4
[Mount]
What=/dev/disk/by-uuid/UUID-della-partizione
Where=/mnt/part4
Type=ext4
Options=defaults
[Install]
WantedBy=local-fs.targetSuccessivamente:
systemctl daemon-reload # carica la nuova 'unit'
systemctl start mnt-part4.mount # monta la partizione
systemctl status mnt-part4.mount # verifica che l'unità è stata caricata e di conseguenza la partizione montata
systemctl enable mnt-part4 # imposta il montaggio della partizione al boot104.4 - Limitare gli utenti con Disk Quota
Installiamo i pacchetti necessari:
apt install quota quotatoolSuccessivamente, nel file /etc/fstab, aggiungo le opzioni usrquota e grpquota in corrispondenza del filesystem che voglio monitorare:
mount -o remount <partizione> # rimonto la partizione di `/etc/fstab` per fargli acquisire le nuove opzioni
quotacheck -avugmcL’ultimo comando fa tutto quanto necessario per inizializzare e monitorare le quote. spiego gli argomenti:
a, controlla tutti i filesystem montati in /etc/fstab (ad eccezione di NFS);v, modalità verbosa;u, applica userquota dove previsto;g, applica groupquota dove previsto;m, non provare a rimontare in sola lettura il filesystem;c, scrive alla radice della relativa partizione i relativi file senza controllare se esistono già.
L’opzione c è necessaria solo al primo quotacheck per creare i seguenti files alla radice del filesystem che si vuole controllare:
- mount-point/quota.user
- mount-point/quota.group
Per abilitare o disabilitare il controllo ora posso eseguire:
quotaon -a # abilita il monitoraggio su tutti i filesystem impostati
quotaon <mount-point> # abilita il monitoraggio di un particolare filesystem
quotaoff -a # disabilita il monitoraggio su tutti i filesystem impostati
quotaoff <mount-point> # disabilita il monitoraggio di un particolare filesystemI check successivi possono anche essere lanciati manualmente:
quotacheck -avugmVediamo gli ultimi comandi:
edquota <nome-utente> # modifica le quote di un utente
edquota -g <group> # modifica le quote di un gruppo
quota <username> # mostra la situazione di un utente
quota -g <group> # mostra la situazione di un gruppo
repquota <mount-point> # mastra la situazione per tutti gli utenti con riferimento ad un particolare filesystem104.5 - chown, chmod, permessi
permessi
Le triplette dei permessi si riferiscono a:
u, (u)ser - utente proprietario del file o cartella;g, (g)roup - gruppo di appartenenza del file o cartella;o, (o)thers - tutti gli altri utenti che non sono i proprietario e non fanno parte del gruppo a cui appartiene il file o la cartella.
E possono essere di:
r, permesso di lettura;w’ permesso di scrittura;x’ permesso di esecuzione.
I permessi possono essere cambiati tramite comando chmod:
chmod o+w <file> # aggiunge il permesso di scrittura ('w') a tutti gli utenti ('o')
chmod ugo-x <file> # elimina il permesso di esecuzione ('x') al proprietario ('u'), agli utenti che fanno parte del gruppo di appartenenza ('g') ed a tutti gli altri ('o')L’assegnazione dei permessi è generalmente effettuata con la modalità ottale. Il significato dei numeri, per utente proprietario, gruppo proprietario e resto degli utenti, è il seguente e vanno sommati per ogni gruppo:
4, permesso di letturar=;2, permesso di scritturaw;1, permesso di esecuzionex.
Pertanto i permessi possono essere anche assegnati come segue:
chmod 775 <file> # corrisponde a `'rwxrwxrw-'`
chmod 644 <file> # corrisponde a `'rw-r--r--'`
chmod 444 <file> # corrisponde a `'r--r--r--'`sticky-bit
L’assegnazione del permesso di scrittura (w) permette l’eliminazione del file anche a chi non ne è strettamente il proprietario.
Per ovviare a ciò, ossia assegnare solo al proprietario la possibilità di eliminare il file ma lasciare agli altri utenti la possibilità di modificarlo (data dal permesso w), è possibile attribuire ad un file uno sticky-bit tramite il seguente comando:
chmod +t <file>In questo modo l’ultimo carattere dei permessi diventa:
t, se per il file non ci sono permessi di esecuzione per il gruppo di utenti altri;T, se per il file ci sono permessi di esecuzione per il gruppo di utenti altri.
Quindi anche se ci sono i permessi di scrittura per il gruppo o gli altri utenti, questi non possono rinominare o eliminare il file ma lo potrà fare solo il proprietario (la cancellazione del file è comunque permessa al proprietario della cartella in cui si trova il file).
Anche lo sticky-bit può essere assegnato con il metodo ottale aggiungendo il numero 1 all’inizio della tripletta dei permessi ottale, ad esempio:
chmod 1777 <file> # corrisponde a 'rwxrwxrwT'
chmod 1776 <file> # corrisponde a 'rwxrwxrwt'
chmod 1770 <file> # corrisponde a 'rwxrwx--t'Lo sticky-bit può anche essere aggiunto ad una cartella:
chmod +t <cartella>In questo modo i files presenti all’interno della cartella potranno essere eliminati solamente dal proprietario del file (o dal proprietario della cartella, come per i file). Si noti come la cartella di sistema /tmp/ abbia lo sticky-bit e ne si capisce anche il senso: chiunque può scrivere nella cartella ma solo il proprietario del file creato può eliminarlo.
set-UID e set-GID
Consentono di eseguire un file (naturalmente a chi ne ha i permessi di esecuzione) con gli stessi privilegi del proprietario (set-UID) o del gruppo (set-GID) di appartenenza del file stesso (per questioni di sicurezza si può applicare soltanto agli eseguibile compilati e non agli script).
Il set-UID e set-GID vengono identificati con il carattere s che si sostituisce al carattere x rispettivamente ai permessi del proprietario o del gruppo.
Il permesso viene attribuito in maniera ottale, insieme allo sticky-bit, tenuto conto dei seguenti valori (da sommare) e mettere in testa alla tripletta ottale di assegnazione dei permessi:
4, set-UID;2, set-GID;1, sticky-bit.
A esempio:
chmod 4775 <file> # solo set-UID
chmod 6644 <file> # sia set-UID che set-GID
chmod 7600 <file> # contemporaneamente set-UID, set-GID e sticky-bit104.5 - chown e chgrp (i permessi)
chgrp <gruppo> <file> # cambia il gruppo proprietario di 'file'
chown <proprietario> <file> # cambia il proprietario di 'file'
chown <proprietario>:<gruppo> <file> # cambia il proprietario ed il gruppo proprietario di 'file'Nota bene:
- per cambiare il gruppo di un file ne si deve essere il proprietario;
- per cambiare il proprietario di un file si deve essere root.
Il comando umask restituisce la “maschera” che viene applicata ai permessi di default di files (666) e cartelle (777). Ciò significa che, quando un utente crea un file oppure una cartella, i permessi per proprietario, gruppo e altri utenti descritti in forma ottale, saranno uguali ai permessi default meno i permessi di umask.
Ad esempio, il valore di default di umask per un utente Linux è pari a 0002 (il primo numero non si conta), quindi i permessi di una cartella creata saranno 775 e per un file invece 664. Per cambiare il valore di umask eseguo:
umask <nuova-maschera-ottale>104.6 - symlink e hardlink in Linux


- nome-file, hardlink e symlink hanno un loro inode all’interno della tabella del filesystem;
- ciascuno di essi punta ad un inode (all’interno del medesimo filesystem) in cui vi sono i dati;
- nome-file e hardlink puntano ai medesimi dati, quindi al medesimo inode;
- symlink punta ad un inode diverso che contiene il path per raggiungere nome-file.
Per i punti che precedono un hardlink non può puntare ad un file che si trova su un filesystem diverso mentre symlink può farlo perchè il path è descritto nei dati a cui punta (questi dati si che si trovano nel medesimo filesystem).
Sempre per le medesime ragioni quando viene spostato (mv) nome-file (all’interno del medesimo filesystem) viene solo variato l’inode del nome e non l’inode dei dati a cui punta e quindi:
- hardlink punta sempre correttamente perchè punta all’inode dei dati (e, nel caso cambiasse verrebbe aggiornato anche =hardlink=);
- symlink punta ad un nome file che è stato spostato e quindi risulta un broken-link.
Se invece nome-file viene spostato su un diverso filesystem quello che succede è che anche i dati del file vengono duplicati e quindi:
- nome-file (spostato) punta al nuovo inode nel nuovo filesystem (sono stati copiati nel nuovo filesystem anche i dati del file lasciandone una copia nel vecchio filesystem in quanto esiste ancora hard-link che punta a loro);
- hardlink punta ancora al vecchio inode nel precedente filesystem che contiene ancora i dati;
- abbiamo però ora 2 file distinti e quindi quando modifico il file partendo da nome-file i dati a cui fa riferimento hardlink non subiscono la stessa modifica e viceversa, insomma il link non esiste sostanzialmente più;
- symlink risulta puntare sempre al nome che è stato spostato e pertanto non esiste più, tanto come nell’esempio precedente di spostamento nel medesimo filesystem.
La conclusione è che spostamenti di hard-link possono causare la duplicazione di un file senza accorgersi, cosa che non può avvenire con il symlink che si corrompe sempre ad ogni spostamento di nome-file.
Ultima due note:
- il numero che segue i permessi di un file o di una directory nell’output del comando
ls -lè il numero di hard-links al medesimo inode dei dati a cui punta anche il file elencato; - il comando
ls -imostra anche l’inode dei dati a cui punta il file o la cartella listati.
104.7 - type, which, whereis, FHS
type <comando> # mostra l'alias se esiste altrimenti...
type <comando> # ...mostra se è un comando interno della shell oppure...
type <comando> # ...mostra il percorso dell'eseguibile
which <comando> # restituisce il primo percorso del comando trovato in '$PATH'
whereis <comando> # restituisce il percorso ed il manuale del comandoFilesystem Hierarchy Standard (FHS) è uno standard che definisce le directory principali ed il loro contenuto nel file-system dei sistemi operativi Unix-like, tra cui i sistemi Linux.
Test sul capitolo 104
Lezioni da n. 77 a n. 86.
Risposte giuste: 12 su 13.
Sezione 6 : Conclusione
Simulazione d’esame - Exam 101
Risposte giuste: 58 su 70.