Capitolo 10. Gestione dei dati

# Capitolo 10. Gestione dei dati

In questo capitolo sono descritti strumenti e trucchi per gestire dati binari e di testo in un sistema Debian.

## 10.1. Condividere, copiare ed archiviare

| Avvertimento
L'accesso in scrittura non coordinato a device a cui si sta attivamente accedendo e a file da parte di processi diversi deve essere evitato per prevenire le race condition. Per evitare ciò devono essere usati i meccanismi di lock dei file utilizzando `flock`(1).

La sicurezza dei dati e la loro condivisione controllata hanno diversi aspetti.

- La creazione di archivi di dati

- L'accesso ad archivi remoti

- La duplicazione

- Il tenere traccia della cronologia delle modifiche

- La facilitazione della condivisione dei dati

- Il prevenire l'accesso non autorizzato ai file

- La rilevazione di modifiche non autorizzate ai file

Queste azioni possono essere realizzate usando una combinazione di strumenti.

- Strumenti di archiviazione e compressione

- Strumenti di copia e sincronizzazione

- file system di rete

- Supporti di archiviazione removibili

- Secure Shell

- Il sistema di autenticazione

- Strumenti per sistemi di controllo delle versioni

- Strumenti crittografici per hash e cifratura

### 10.1.1. Strumenti di archiviazione e compressione

Ecco una tabella riassuntiva degli strumenti di archiviazione e compressione disponibili per il sistema Debian.

Tabella 10.1. Elenco di strumenti di archiviazione e compressione

pacchetto | popcon | dimensione | estensione | comando | commento
--- | --- | --- | --- | --- | ---
`tar` | V:889, I:999 | 3085 | `.tar` | `tar`(1) | strumento di archiviazione standard (standard de facto)
`cpio` | V:404, I:998 | 1201 | `.cpio` | `cpio`(1) | strumento di archiviazione Unix in stile System V, da usare con `find`(1)
`binutils` | V:184, I:636 | 1119 | `.ar` | `ar`(1) | strumento di archiviazione per la creazione di librerie statiche
`fastjar` | V:1, I:10 | 183 | `.jar` | `fastjar`(1) | strumento di archiviazione per Java (simile a zip)
`pax` | V:5, I:10 | 167 | `.pax` | `pax`(1) | nuovo strumento POSIX di archiviazione, compromesso tra `tar` e `cpio`
`gzip` | V:885, I:999 | 256 | `.gz` | `gzip`(1), `zcat`(1), … | utilità GNU di compressione LZ77 (standard de facto)
`bzip2` | V:168, I:972 | 114 | `.bz2` | `bzip2`(1), `bzcat`(1), … | utilità per compressione con ordinamento dei blocchi Burrows-Wheeler con maggiore rapporto di compressione di `gzip`(1) (più lenta di `gzip` con sintassi simile)
`lzma` | V:0, I:11 | 349 | `.lzma` | `lzma`(1) | utilità di compressione LZMA con maggiore rapporto di compressione di `gzip`(1) (deprecata)
`xz-utils` | V:309, I:980 | 1475 | `.xz` | `xz`(1), `xzdec`(1), … | utilità di compressione XZ con maggiore rapporto di compressione di `bzip2`(1) (più lenta di `gzip`, ma più veloce di `bzip2`; sostituto dell'utilità di compressione LZMA)
`zstd` | V:265, I:777 | 2313 | `.zstd` | `zstd`(1), `zstdcat`(1), … | utilità di compressione Zstandard veloce senza perdita di dati
`p7zip` | V:8, I:237 | 8 | `.7z` | `7zr`(1), `p7zip`(1) | strumento di archiviazione file 7-Zip con alto rapporto di compressione (compressione LZMA)
`p7zip-full` | V:27, I:259 | 12 | `.7z` | `7z`(1), `7za`(1) | strumento di archiviazione file 7-Zip con alto rapporto di compressione (compressione LZMA e altre)
`lzop` | V:12, I:137 | 164 | `.lzo` | `lzop`(1) | utilità di compressione LZO con velocità di compressione e decompressione più alta di quella di `gzip`(1) (più basso rapporto di compressione di `gzip` con sintassi simile)
`zip` | V:50, I:367 | 627 | `.zip` | `zip`(1) | InfoZIP: strumento di archiviazione e compressione per DOS
`unzip` | V:116, I:759 | 387 | `.zip` | `unzip`(1) | InfoZIP: strumento di estrazione di archivi e decompressione per DOS

| Avvertimento
Non impostare la variabile "`$TAPE`" a meno che non si sappia esattamente cosa aspettarsi. Cambia il comportamento di `tar`(1).

- Gli archivi `tar`(1) compressi con gzip usano l'estensione di file "`.tgz`" o "`.tar.gz`".

- Gli archivi `tar`(1) compressi con xz usano l'estensione di file "`.txz`" o "`.tar.xz`".

- La popolarità dei metodi di compressione negli strumenti FOSS come `tar`(1) è cambiata nel tempo nel modo seguente `gzip` → `bzip2` → `xz`

- `cp`(1), `scp`(1) e `tar`(1) possono avere alcune limitazioni per file speciali. `cpio`(1) è più versatile.

- `cpio`(1) è progettato per essere usato con `find`(1) ed altri comandi adatti per creare script di backup, dato che la porzione di selezione dei file dello script può essere testata in modo autonomo.

- La struttura interna dei file di dati di LibreOffice è quella dei file «`.jar`» che può essere aperta anche da `unzip`.

- Lo strumento multipiattaforma di fatto usato per gli archivi è `zip`. Usarlo come «`zip -rX`» per ottenere la massima compatibilità. Usare anche l'opzione «`-s`» se è importante la dimensione massima dei file.

### 10.1.2. Strumenti di copia e sincronizzazione

Ecco una tabella riassuntiva dei semplici strumenti di copia e backup disponibili in un sistema Debian.

Tabella 10.2. Elenco di strumenti di copia e sincronizzazione

pacchetto | popcon | dimensione | strumento | funzione
--- | --- | --- | --- | ---
`coreutils` | V:892, I:999 | 18457 | GNU cp | copia file e directory localmente ("-a" per modalità ricorsiva)
`openssh-client` | V:898, I:996 | 5133 | scp | copia file e directory da remoto (client, "`-r`" per modalità ricorsiva)
`openssh-server` | V:745, I:804 | 3502 | sshd | copia file e directory da remoto (server remoto)
`rsync` | V:200, I:539 | 814 |  | sincronizzazione e backup in remoto unidirezionale
`unison` | V:3, I:13 | 14 |  | sincronizzazione e backup in remoto bidirezionale

La copia dei file con `rsync`(8) offre un insieme di funzionalità più ricco di altri strumenti.

- l'algoritmo delta-transfer, che invia solamente le differenze tra il file sorgente ed il file esistente nella destinazione

- algoritmo veloce di verifica (predefinito) che cerca i file la cui dimensione o il cui orario di ultima modifica sono cambiati

- opzioni "`--exclude`" e "`--exclude-from`" simili a quelle di `tar`(1)

- sintassi con "una barra / alla fine della directory sorgente" che evita di dover creare un livello aggiuntivo di directory nella destinazione

| Suggerimento
Gli strumenti di controllo delle versioni VCS (Version control system) in Tabella 10.14, «Elenco di altri strumenti per sistemi di controllo delle versioni» possono essere usati come strumenti di copia e sincronizzazione multidirezionali.

### 10.1.3. Esempi di invocazione per archivi

Ecco diversi modi di archiviare ed estrarre archivi con l'intero contenuto della directory "`./sorgente`", usando diversi strumenti.

GNU `tar`(1):

    $ tar -cvJf archive.tar.xz ./source
    $ tar -xvJf archive.tar.xz

In alternativa usare i comandi seguenti.

    $ find ./source -xdev -print0 | tar -cvJf archive.tar.xz --null -T -

`cpio`(1):

    $ find ./source -xdev -print0 | cpio -ov --null > archive.cpio; xz archive.cpio
    $ zcat archive.cpio.xz | cpio -i

### 10.1.4. Esempi di invocazione per la copia

Ecco diversi modi di copiare l'intero contenuto della directory "`./sorgente`", usando diversi strumenti.

- Copia locale: directory "`./sorgente`" → directory "`/dest`"

- Copia remota: directory "`./sourgente`" sull'host locale → directory "`/dest`" sull'host "`utente@host.dom`"

`rsync`(8):

    # cd ./source; rsync -aHAXSv . /dest
    # cd ./source; rsync -aHAXSv . user@host.dom:/dest

In alternativa si può usare la sintassi con "una barra / alla fine della directory sorgente".

    # rsync -aHAXSv ./source/ /dest
    # rsync -aHAXSv ./source/ user@host.dom:/dest

In alternativa usare i comandi seguenti.

    # cd ./source; find . -print0 | rsync -aHAXSv0 --files-from=- . /dest
    # cd ./source; find . -print0 | rsync -aHAXSv0 --files-from=- . user@host.dom:/dest

GNU `cp`(1) e openSSH `scp`(1):

    # cd ./source; cp -a . /dest
    # cd ./source; scp -pr . user@host.dom:/dest

GNU `tar`(1):

    # (cd ./source && tar cf - . ) | (cd /dest && tar xvfp - )
    # (cd ./source && tar cf - . ) | ssh user@host.dom '(cd /dest && tar xvfp - )'

`cpio`(1):

    # cd ./source; find . -print0 | cpio -pvdm --null --sparse /dest

In tutti gli esempi contenenti "`.`", si può sostituire "`.`" con "`pippo`" per copiare i file dalla directory "`./sorgente/pippo`" alla directory "`/dest/pippo`".

In tutti gli esempi contenenti "`.`", si può sostituire "`.`" con il percorso assoluto "`/percorso/di/sorgente/pippo`" per evitare di fare "`cd ./sorgente;`". I file verranno copiati in posizioni diverse a seconda dello strumento utilizzato, come descritto qui di seguito.

- in "`/dest/pippo`": `rsync`(8), GNU `cp`(1) e `scp`(1)

- "`/dest/percorso/di/sorgente/pippo`": GNU `tar`(1) e `cpio`(1)

| Suggerimento
`rsync`(8) e GNU `cp`(1) hanno l'opzione "`-u`" per saltare i file che sono più recenti nella destinazione.

### 10.1.5. Esempi di invocazione per la selezione di file

`find`(1) viene usato per selezionare i file per i comandi di archiviazione e copia (vedere Sezione 10.1.3, «Esempi di invocazione per archivi» e Sezione 10.1.4, «Esempi di invocazione per la copia») o per `xargs`(1) (vedere Sezione 9.4.9, «Ripetere un comando su diversi file»). Questo funzionamento può essere migliorato usando le sue opzioni di comando.

La sintassi base di `find`(1) può essere riassunta nel modo seguente.

- Gli argomenti condizionali sono valutati da sinistra a destra.

- Questa valutazione si ferma una volta che il risultato è determinato.

- L'operatore "OR logico" (specificato con "`-o`" tra condizioni) ha una precedenza più bassa dell'operatore "AND logico" (specificato da "`-a`" o dall'assenza di un operatore tra condizioni).

- L'operatore "NOT logico" (specificato da "`!`" prima di una condizione) ha una precedenza più alta di un operatore "AND logico".

- L'opzione "`-prune`" restituisce sempre una condizione di VERO logico e, se si tratta di una directory, la ricerca si ferma a questo punto.

- L'opzione "`-name` trova corrispondenze con il nome base del file tramite espressioni glob di shell (vedere Sezione 1.5.6, «Glob della shell»), ma fa corrispondenza anche con il carattere iniziale "`.`" con l'uso di metacaratteri come "`*`" e "`?`". (Nuova funzionalità POSIX.)

- L'opzione "`-regex`" trova corrispondenze con il percorso completo usando, in modo predefinito, BRE in stile emacs (vedere Sezione 1.6.2, «Espressioni regolari»).

- L'opzione "`-size`" trova corrispondenze con file in base alla loro dimensione (valori preceduti da "`+`" o "`-`" per cercare dimensioni, rispettivamente, più grandi o piccole del valore).

- L'opzione "`-newer`" trova corrispondenze con file più recenti di quello specificato come argomento dell'opzione.

- L'opzione "`-print0`" restituisce sempre il valore logico VERO e stampa il nome file completo (terminato dal carattere null) sullo standard output.

`find`(1) è spesso usato con uno stile di invocazione come il seguente.

    # find /path/to \
        -xdev -regextype posix-extended \
        -type f -regex ".*\.cpio|.*~" -prune -o \
        -type d -regex ".*/\.git" -prune -o \
        -type f -size +99M -prune -o \
        -type f -newer /path/to/timestamp -print0

Il comando precedente si traduce nelle azioni seguenti.

1. Cercare tutti i file a partire da "`/percorso/di`"

2. Limitare globalmente la ricerca al file system da cui è richiamato e usare espressioni regolari ERE (vedere Sezione 1.6.2, «Espressioni regolari»)

3. Escludere i file che corrispondono all'espressione regolare "`.*\.cpio`" o "`.*~`" dalla ricerca fermando la loro elaborazione

4. Escludere le directory che corrispondono all'espressione regolare "`.*/\.git`" dalla ricerca fermando la loro elaborazione

5. Escludere i file più grandi di 99 Megabyte (unità di 1048576 byte) dalla ricerca fermando la loro elaborazione

6. Stampare i nomi di file che soddisfano le condizioni di ricerca precedenti e che siano più recenti di "`/percorso/di/marcaturaorario`"

Notare nell'esempio precedente l'uso della parte di comando "`-prune -o` per escludere file.

| Nota
Alcune opzioni per `find`(1) potrebbero non essere supportate per i sistemi *nix non Debian. In questi casi, cambiare le invocazioni in quelle adatte corrispondenti e sostituire "`-print0`" con "`-print`". Potrebbe essere necessario modificare anche comandi correlati.

### 10.1.6. Supporti di archiviazione

Quando si deve scegliere il supporto di archiviazione di dati informatici per un importante archivio di dati, si dovrebbe porre attenzione alle limitazioni dei supporti. Per piccoli backup di dati personali, io uso CD-R e DVD-R scegliendoli in base alla marca del produtttore e conservandoli in un ambiente fresco, all'ombra, asciutto e pulito. (I supporti di archiviazione a nastro sembrano molto popolari per gli usi professionali.)

| Nota
Le casseforti a prova di fuoco sono pensate per i documenti cartacei. La maggior parte dei supporti di archiviazione di dati informatici ha una tolleranza più bassa alle alte temperature rispetto alla carta. Di solito mi affido a copie multiple cifrate sicure conservate in diverse posizioni sicure.

Durata di vita ottimistica di diversi supporti di archiviazione da dati raccolti in rete (per lo più dalle informazioni dei produttori).

- 100+ anni: carta senza acidi con inchiostro

- 100 anni: supporti ottici (CD/DVD, CD/DVD-R)

- 30 anni: supporti magnetici (nastri, dischetti floppy)

- 20 anni: supporti ottici a cambio di fase (CD-RW)

Questi tempi non tengono conto dei danni meccanici causati dal maneggiamento, ecc.

Cicli di scrittura ottimistici di diversi supporti di archiviazione da dati raccolti in rete (per lo più dalle informazioni dei produttori).

- 250,000+ cicli: unità a disco fisso

- 10,000+ cicli: memoria flash

- 1,000 cicli: CD/DVD-RW

- 1 ciclo: CD/DVD-R, carta

| Attenzione
I valori di durata di vita e dei cicli di scrittura riportati non dovrebbero essere usati per prendere decisioni riguardo all'archiviazione di dati critici. Consultare le informazioni specifiche per ciascun prodotto forniti dal produttore.

| Suggerimento
Dato che i CD/DVD-R e la carta hanno un solo ciclo di scrittura, prevengono per loro stessa natura le perdite accidentali di dati per sovrascrittura. Questo è un vantaggio!

| Suggerimento
Se è necessario fare backup frequenti e veloci di una grande quantità di dati, un disco fisso su un host remoto connesso con una connessione veloce, potrebbe essere l'unica soluzione realistica.

| Suggerimento
Se si usano supporti riscrivibili per i backup, l'uso di file system come btrfs o zfs che supportano solo istantanee in sola lettura potrebbe essere una buona idea.

### 10.1.7. Supporti di archiviazione removibili

Un support di archiviazione removibile può essere uno dei seguenti.

- Unità flash USB

- Unità a disco fisso

- Unità a dischi ottici

- Fotocamera digitale

- Lettore audio digitale

Possono essere connessi in uno dei modi seguenti.

- USB

- IEEE 1394 / FireWire

- Scheda PC

Gli ambienti desktop moderni, come GNOME e KDE, possono montare questi dispositivi removibili automaticamente senza una voce corrispondente in "`/etc/fstab`".

- Il pacchetto `udisks2` fornisce un demone e le utilità associate per montare e smontare questi dispositivi.

- D-bus crea eventi per dare inizio ai processi automatici.

- PolicyKit fornisce i privilegi necessari.

| Suggerimento
I dispositivi montati automaticamente hanno l'opzione di mount "`uhelper=`" che viene usata da `umount`(8).

| Suggerimento
Nei moderni ambienti desktop il montaggio automatico avviene solo quando i device dei supporti removibili non sono elencati in "`/etc/fstab`".

Il punto di mount negli ambienti desktop moderni viene scelto come "`/media/nomeutente/etichetta_disco`" che può essere personalizzato nel modo seguente.

- `mlabel`(1) per file system FAT

- `genisoimage`(1) con l'opzione "`-V`" per file system ISO9660

- `tune2fs`(1) con l'opzione "`-L`" per file system ext2/ext3/ext4

| Suggerimento
Può essere necessario fornire come opzione di montaggio la scelta della codifica (vedere Sezione 8.1.3, «Codifica per i nomi di file»).

| Suggerimento
L'uso del menu GUI per smontare un file system può rimuovere il suo nodo di device generato dinamicamente come "`/dev/sdc`". Se si desidera mantenere il suo nodo di device, smontarlo con il comando `umount`(8) dal prompt di shell.

### 10.1.8. Scelta del file system per la condivisione di dati

Quando si condividono dati con un altro sistema attraverso dispositivi di archiviazione removibili, quest'ultimi andrebbero formattati con un filesystem comune supportato da entrambi i sistemi. Quello che segue è un elenco delle scelte possibili per il file system.

| Nota
"Hard disk like device" means storage devices such as HDD / SSD / USB flash drive / ... . Their device names have several variants; `/dev/sda`, `/dev/nvme0`, `/dev/mmcblk0`, ... .

Tabella 10.3. Elenco di possibili scelte per il file system di dispositivi di archiviazione removibili con scenari di uso tipici

nome del file system | scenario di uso tipico
--- | ---
FAT12 | condivisione interpiattaforma di dati su dischetti floppy (<32MiB)
FAT16 | condivisione interpiattaforma di dati su dispositivi come piccoli dischi fissi (<2GiB)
FAT32 | condivisione interpiattaforma di dati su dispositivi come grandi dischi fissi (<8TiB, supportato da sistemi più recenti di MS Windows95 OSR2)
exFAT | condivisione interpiattaforma di dati su dispositivi come grandi dischi fissi (<512TiB, supportato da WindowsXP, Mac OS X Snow Leopard 10.6.5 e kernel Linux sin dal rilascio 5.4.
NTFS | condivisione interpiattaforma di dati su dispositivi come grandi dischi fissi (supportato nativamente su MS Windows NT e versioni successive e supportato da NTFS-3G attraverso FUSE in Linux)
ISO9660 | condivisione interpiattaforma di dati statici su CD-R e DVD+/-R
UDF | scrittura incrementale di dati su CD-R e DVD+/-R (nuovo)
MINIX | archiviazione, efficiente in termini di spazio, di file dati unix su dischetti floppy
ext2 | condivisione di dati su dispositivi come dischi fissi con sistemi Linux più vecchi
ext3 | condivisione di dati su dispositivi come dischi fissi con sistemi Linux più vecchi
ext4 | condivisione di dati su dispositivi come dischi fissi con sistemi Linux recenti
btrfs | condivisione di dati su dispositivi come dischi fissi con sistemi Linux recenti con istantanee in sola lettura

| Suggerimento
Vedere Sezione 9.9.1, «Cifratura di dischi removibili con dm-crypt/LUKS» per la condivisione interpiattaforma di dati usando cifratura a livello di dispositivo.

Il file system FAT è supportato da quasi tutti i sistemi operativi moderni ed è piuttosto utile per scopi di scambio di dati attraverso supporti come dischi fissi removibili.

Quando si formatta un dispositivo come un disco fisso removibile con il file system FAT per la condivisione interpiattaforma di dati, le scelte seguenti dovrebbero essere quelle più sicure.

- Partizionare con `fdisk`(8), `cfdisk`(8) o `parted`(8) (vedere Sezione 9.6.2, «Configurazione del partizionamento dei dischi») creando un'unica partizione primaria e marcarla nel modo seguente.

  - Tipo "6", cioè FAT16, per supporti più piccoli di 2GB.

  - Tipo "c", cioè FAT32 (LBA), per supporti più grandi.

- Formattare la partizione primaria con `mkfs.vfat`(8) nel modo seguente.

  - Per FAT16, semplicemente con il suo nome di device, ad esempio "`/dev/sda1`".

  - Per FAT32, con il suo nome di device e l'opzione esplicita, ad esempio "`-F 32 /dev/sda1`"

Quando si usano i file system FAT o ISO9660 per la condivisione dei dati, per essere sicuri dei risultati, si dovrebbero considerare i seguenti aspetti.

- Archiviare prima i file in un file di archivio usando `tar`(1) o `cpio`(1) per mantenere i nomi di file lunghi, i collegamenti simbolici, i permessi Unix sui file originali e le informazioni sui proprietari.

- Suddividere il file di archivio in pezzi più piccoli di 2 GiB con il comando `split`(1) per proteggerli da limitazioni sulla dimensione dei file.

- Cifrare il file archivio per proteggere i suoi contenuti da accesso non autorizzato.

| Nota
Il file system FAT, per sua stessa natura, permette una dimensione massima per i file di `(2^32 - 1) byte = (4GiB - 1 byte)`. Per alcune applicazioni su sistemi operativi a 32 bit più vecchi, la dimensione massima per i file era ancora più piccola: `(2^31 - 1) byte = (2GiB - 1 byte)`. Debian non soffre di quest'ultima limitazione.

| Nota
La stessa Microsoft non raccomanda l'uso di FAT per le unità o le partizioni più grandi di 200 MB. Microsoft evidenzia le sue limitazioni, quali un uso inefficiente dello spazio su disco, nel documento "Overview of FAT, HPFS, and NTFS File Systems". Naturalmente per Linux si dovrebbe normalmente usare il file system ext4.

| Suggerimento
Per maggiori informazioni sui file system e sull'accesso ad essi, leggere il "Filesystems HOWTO".

### 10.1.9. Condividere dati attraverso una rete

Quando si condividono dati con un altro sistema attraverso una rete, si dovrebbero tenere a mente i servizi comuni. Ecco alcuni suggerimenti.

Tabella 10.4. Elenco dei servizi di rete da scegliere in base allo scenario di uso tipico

servizio di rete | descrizione dello scenario di uso tipico
--- | ---
file system montato di rete SMB/CIFS con Samba | condivisione di file attraverso "rete Microsoft Windows", vedere `smb.conf`(5) e The Official Samba 3.x.x HOWTO and Reference Guide o il pacchetto `samba-doc`
file system montato di rete NFS con il kernel Linux | condivisione di file attraverso "rete Unix/Linux", vedere `exports`(5) e Linux NFS-HOWTO
servizio HTTP | condivisione di file tra client/server web
servizio HTTPS | condivisione di file tra client/server web con SSL (Secure Sockets Layer) cifrato o TLS (Transport Layer Security)
servizio FTP | condivisione di file tra client/server FTP

Sebbene questi file system montati in rete e metodi di trasferimento di file attraverso la rete siano piuttosto comodi per la condivisione dei dati, possono essere non sicuri. La loro connessione di rete deve essere resa sicura nel modo seguente.

- Cifrarli con SSL/TLS

- Usarli in tunnel SSH

- Usarli in tunnel VPN

- Limitarli dietro ad un firewall sicuro

Vedere anche Sezione 6.5, «Altri server di rete» e Sezione 6.6, «Altri client di rete».

## 10.2. Backup e ripristino

Tutti sanno che i computer a volte si danneggiano oppure errori umani causano danni al sistema e ai dati. Le operazioni di backup e ripristino sono una parte essenziale di un'amministrazione di sistema di successo. Tutte i possibili modi in cui si possono creare danni si verificano prima o poi.

| Suggerimento
Mantenere il proprio sistema di backup semplice e fare il backup di sistema spesso. Avere dati di backup è più importante della qualità tecnica del metodo di backup.

### 10.2.1. Politica di backup e ripristino

Ci sono 3 fattori chiave che determinano la reale politica di backup e ripristino.

1. Sapere di cosa fare il backup ed il ripristino

   - I file dati direttamente creati dall'utente: in "`~/`"

   - I file dati creati da applicazioni usate dall'utente: dati in "`/var/`" (tranne "`/var/cache/`", "`/var/run/`" e "`/var/tmp/`")

   - File di configurazione del sistema: dati in "`/etc/`"

   - Programmi locali: dati in "`/usr/local/`" o "`/opt/`"

   - Informazioni di installazione del sistema: un memorandum in puro testo sui passi chiave (partizioni, …)

   - Insiemi di dati comprovati: confermati da operazioni preventive sperimentali di ripristino

     - Compito di cron come processo di un utente; file nella directory "`/var/spool/cron/crontabs`" e riavvio di `cron`(8). Vedere Sezione 9.4.14, «Pianificare compiti in modo regolare» per `cron`(8) e `crontab`(1).

     - Compiti temporizzati di systemd come processi utente: file nella directory "`~/.config/systemd/user`". Vedere `systemd.timer`(5) e `systemd.service`(5).

     - Compiti automatici all'avvio come processi utente: file nella directory "`~/.config/autostart`". Vedere Specifica per l'avvio automatico di applicazioni desktop.

2. Sapere come fare il backup ed il ripristino

   - Rendere sicura l'archiviazione dei dati: protezione da sovrascritture e fallimenti del sistema

   - Backup frequenti: backup pianificati

   - Backup ridondanti: mirror di dati

   - Procedura a prova di idioti: singolo facile comando di backup

3. Valutazione dei rischi e dei costi

   - Rischio della perdita di dati

     - I dati dovrebbere come minimo essere su partizioni del disco diverse, preferibilmente su dischi e macchine diversi per sopravvivere alla corruzione del file system. È meglio archiviare i dati importanti su un file system in sola lettura. [4]

   - Rischio dell'accesso non consentito a dati

     - Dati sensibili relativi all'identità dell'utente, come "`/etc/ssh/ssh_host_*_key`", "`~/.gnupg/*`", "`~/.ssh/*`", "`~/.local/share/keyrings/*`", "`/etc/passwd`", "`/etc/shadow`", "`popularity-contest.conf`", "`/etc/ppp/pap-secrets`" e "`/etc/exim4/passwd.client`" dovrebbero essere archiviati in backup cifrati [5] (Vedere Sezione 9.9, «Suggerimenti per la cifratura dei dati».)

     - Non inserire mai in modo fisso la password di login nel sistema o la passphrase di decifrazione nel codice di alcun script, nemmeno in un sistema fidato. (Vedere Sezione 10.3.6, «Portachiavi per le password».)

   - Modi in cui le cose possono andare storte e loro probabilità

     - L'hardware (specialmente gli HDD) si rompe

     - I file system possono diventare corrotti e i dati in essi possono venire persi

     - Non ci si può fidare che i sistemi di archiviazione in remoto non abbiano falle di sicurezza.

     - Una protezione con password deboli può essere facilmente compromessa

     - Il sistema dei permessi dei file può venir compromesso

   - Risorse necessarie per il backup: umane, hardware, software, …

     - Backup automatici pianificati con compiti di cron o temporizzati di systemd

| Suggerimento
Si possono ripristinare i dati di configurazione di debconf con "`debconf-set-selections debconf-selections`" ed i dati delle selezioni di dpkg con "`dpkg --set-selection <dpkg-selections.list`".

| Nota
Non fare il backup dei contenuti dei pseudo file system che si trovano in `/proc`, `/sys`, `/tmp` e `/run` (vedere Sezione 1.2.12, «procfs e sysfs» e Sezione 1.2.13, «tmpfs»). A meno di non sapere esattamente ciò che si sta facendo, sono un'enorme mole di dati senza utilità.

| Nota
Durante il backup dei dati può essere preferibile fermare alcuni demoni applicativi come l'MTA (vedere Sezione 6.2.4, «Agente di trasporto della posta (MTA)»).

### 10.2.2. Suite con utilità di backup

Quello che segue è un elenco di importanti suite di utilità di backup disponibili in un sistema Debian

Tabella 10.5. Elenco di suite con utilità di backup

pacchetto | popcon | dimensione | descrizione
--- | --- | --- | ---
`bacula-common` | V:6, I:7 | 2501 | Bacula: backup, ripristino e controllo in rete - file comuni di supporto
`bacula-client` | V:0, I:2 | 199 | Bacula: backup, ripristino e controllo in rete - metapacchetto client
`bacula-console` | V:0, I:2 | 112 | Bacula: backup, ripristino e controllo in rete - console testuale
`bacula-server` | I:0 | 199 | Bacula: backup, ripristino e controllo in rete - metapacchetto server
`amanda-common` | V:0, I:2 | 9851 | Amanda: Advanced Maryland Automatic Network Disk Archiver (Librerie)
`amanda-client` | V:0, I:2 | 1099 | Amanda: Advanced Maryland Automatic Network Disk Archiver (Client)
`amanda-server` | V:0, I:0 | 1093 | Amanda: Advanced Maryland Automatic Network Disk Archiver (Server)
`backuppc` | V:1, I:1 | 3088 | BackupPC è un sistema ad altre prestazioni di qualità professionale per il backup di PC (basato su dischi)
`duplicity` | V:6, I:50 | 2649 | backup incrementali (remoti)
`deja-dup` | V:30, I:45 | 5031 | Interfaccia GUI per duplicity
`borgbackup` | V:12, I:28 | 3478 | backup (remoto) con deduplicazione
`borgmatic` | V:3, I:4 | 946 | strumento ausiliario per borgbackup
`rdiff-backup` | V:2, I:7 | 1207 | backup incrementali (remoti)
`restic` | V:5, I:10 | 24708 | backup incrementali (remoti)
`backupninja` | V:2, I:2 | 360 | sistema di meta-backup leggero ed estensibile
`slbackup` | V:0, I:0 | 147 | backup incrementali (remoti)
`backup-manager` | V:0, I:0 | 573 | strumento di backup a riga di comando
`backup2l` | V:0, I:0 | 110 | strumento di backup/ripristino per supporti montabile (basato su dischi) che richiede bassa manutenzione

Gli strumenti di backup hanno una propria specializzazione.

- Mondo Rescue è un sistema di backup per facilitare il ripristino veloce di un sistema completo a partire da backup su CD/DVD ecc., senza dover affrontare il normale processo di installazione del sistema.

- Bacula, Amanda e BackupPC sono suite di utilità di backup complete che sono pensate per backup regolari in rete.

- Duplicity e Borg sono utilità per backup più semplici per le postazioni di lavoro tipiche.

### 10.2.3. Suggerimenti per i backup

Per una postazione di lavoro personale, utilità da suite di backup complete pensate per ambienti server possono non essere adatte. Allo stesso tempo le utilità di backup esistenti per le postazioni di lavoro possono avere alcune limitazioni.

Ecco alcuni suggerimenti per rendere più facili i backup con un minimo sforzo da parte dell'utente. Queste tecniche possono essere utilizzati con qualsiasi utilità di backup.

Per illustrare la cosa, supponiamo che il nome dell'utente principale e del suo gruppo siano `penguin` e si creerà un esempio di script di backup e per istantanea "`/usr/local/bin/bkss.sh`" con:

    #!/bin/sh -e
    SRC="$1" # source data path
    DSTFS="$2" # backup destination filesystem path
    DSTSV="$3" # backup destination subvolume name
    DSTSS="${DSTFS}/${DSTSV}-snapshot" # snapshot destination path
    if [ "$(stat -f -c %T "$DSTFS")" != "btrfs" ]; then
      echo "E: $DESTFS needs to be formatted to btrfs" >&2 ; exit 1
    fi
    MSGID=$(notify-send -p "bkup.sh $DSTSV" "in progress ...")
    if [ ! -d "$DSTFS/$DSTSV" ]; then
      btrfs subvolume create "$DSTFS/$DSTSV"
      mkdir -p "$DSTSS"
    fi
    rsync -aHxS --delete --mkpath "${SRC}/" "${DSTFS}/${DSTSV}"
    btrfs subvolume snapshot -r "${DSTFS}/${DSTSV}" ${DSTSS}/$(date -u --iso=min)
    notify-send -r "$MSGID" "bkup.sh $DSTSV" "finished!"

Qui viene usato solo lo strumento di base `rsync`(1) per facilitare il backup di sistema e lo spazio di archiviazione viene usato efficientemente da Btrfs.

| Suggerimento
Notare che l'autore usa uno script di shell personale simile "bss: Btrfs Subvolume Snapshot Utility" per le sue postazioni di lavoro.

#### 10.2.3.1. Backup con GUI

Ecco un esempio di come impostare un backup con GUI con un unico clic.

- Preparare un dispositivo USB di archiviazione da usare per il backup.

  - Formattare un dispositivo USB di archiviazione con una partizione in btrfs con etichetta chiamata "`BKUP`". Può essere cifrata (vedere Sezione 9.9.1, «Cifratura di dischi removibili con dm-crypt/LUKS»).

  - Connetterlo al sistema. Il sistema desktop dovrebbe montarlo automaticamente come "`/media/penguin/BKUP`".

  - Eseguire "`sudo chown penguin:penguin /media/penguin/BKUP`" per renderlo scrivibile dall'utente.

- Creare "`~/.local/share/applications/BKUP.desktop`" seguendo le tecniche descritte in Sezione 9.4.10, «Avviare un programma dalla GUI», come:

      [Desktop Entry]
      Name=bkss
      Comment=Backup and snapshot of ~/Documents
      Exec=/usr/local/bin/bkss.sh /home/penguin/Documents /media/penguin/BKUP Documents
      Type=Application

Per ogni clic nella GUI, viene fatto il backup dei dati da "`~/Documenti`" in un dispositivo USB di archiviazione e viene creata un'istantanea in sola lettura.

#### 10.2.3.2. Backup attivato da eventi di mount

Ecco un esempio di come impostare un backup automatico attivato da un evento di mount.

- Preparare un dispositivo USB di archiviazione da usare per il backup come in Sezione 10.2.3.1, «Backup con GUI».

- Creare un file con un'unità di servizio di systemd "`~/.config/systemd/user/back-BKUP.service`", come:

      [Unit]
      Description=USB Disk backup
      Requires=media-%u-BKUP.mount
      After=media-%u-BKUP.mount

      [Service]
      ExecStart=/usr/local/bin/bkss.sh %h/Documents /media/%u/BKUP Documents
      StandardOutput=append:%h/.cache/systemd-snap.log
      StandardError=append:%h/.cache/systemd-snap.log

      [Install]
      WantedBy=media-%u-BKUP.mount

- Abilitare questa configurazione con unità di systemd usando:

       $ systemctl --user enable bkup-BKUP.service

Per ogni evento di mount, viene fatto il backup dei dati da "`~/Documenti`" in un dispositivo USB di archiviazione e viene creata un'istantanea in sola lettura.

Si possono chiedere i nomi delle unità di mount che systemd ha attualmente in memoria al gestore del servizio dell'utente in uso con "`systemctl --user list-units --type=mount`".

#### 10.2.3.3. Backup attivato da un evento timer

Ecco un esempio di come impostare un backup automatico attivato da un evento di mount.

- Preparare un dispositivo USB di archiviazione da usare per il backup come in Sezione 10.2.3.1, «Backup con GUI».

- Creare un file con un'unità timer di systemd "`~/.config/systemd/user/snap-Documents.timer`", come:

      [Unit]
      Description=Run btrfs subvolume snapshot on timer
      Documentation=man:btrfs(1)

      [Timer]
      OnStartupSec=30
      OnUnitInactiveSec=900

      [Install]
      WantedBy=timers.target

- Creare un file di unità di servizio di systemd "`~/.config/systemd/user/snap-Documents.service`", come:

      [Unit]
      Description=Run btrfs subvolume snapshot
      Documentation=man:btrfs(1)

      [Service]
      Type=oneshot
      Nice=15
      ExecStart=/usr/local/bin/bkss.sh %h/Documents /media/%u/BKUP Documents
      IOSchedulingClass=idle
      CPUSchedulingPolicy=idle
      StandardOutput=append:%h/.cache/systemd-snap.log
      StandardError=append:%h/.cache/systemd-snap.log

- Abilitare questa configurazione con unità di systemd usando:

       $ systemctl --user enable snap-Documents.timer

Per ogni evento timer, viene fatto il backup dei dati da "`~/Documenti`" in un dispositivo USB di archiviazione e viene creata un'istantanea in sola lettura.

Si possono chiedere i nomi delle unità timer che systemd ha attualmente in memoria al gestore del servizio dell'utente in uso con "`systemctl --user list-units --type=timer`".

Per i sistemi desktop moderni questo approccio che usa systemd può offrire un controllo più dettagliato rispetto a quelli Unix tradizionali che usano `at`(1), `cron`(8) o `anacron`(8).

## 10.3. Infrastruttura di sicurezza dei dati

L'infrastruttura di sicurezza dei dati viene fornita dalla combinazione di strumenti di cifratura dei dati, strumenti message digest e strumenti di firma.

Tabella 10.6. Elenco di strumenti per l'infrastruttura di sicurezza dei dati

pacchetto | popcon | dimensione | comando | descrizione
--- | --- | --- | --- | ---
`gnupg` | V:367, I:872 | 468 | `gpg`(1) | GNU Privacy Guard - strumento OpenPGP di cifratura e firma
`gpgv` | V:258, I:955 | 559 | `gpgv`(1) | GNU Privacy Guard - strumento OpenPGP di verifica delle firme
`sq` | V:0, I:17 | 22408 | `sq`(1) | Sequoia-PGP - strumento OpenPGP di cifratura e firma
`sqv` | V:324, I:406 | 1813 | `sqv`(1) | Sequoia-PGP - OpenPGP signature Sequoia-PGP - strumento OpenPGP di verifica delle firme
`paperkey` | V:1, I:13 | 58 | `paperkey`(1) | estrae solamente le informazioni segrete da chiavi OpenPGP segrete
`cryptsetup` | V:30, I:80 | 465 | `cryptsetup`(8), … | utilità per la cifratura dm-crypt per i device a blocchi con supporto di LUKS
`coreutils` | V:892, I:999 | 18457 | `md5sum`(1) | calcola e controlla message digest MD5
`coreutils` | V:892, I:999 | 18457 | `sha1sum`(1) | calcola e controlla message digest SHA1
`openssl` | V:834, I:995 | 2503 | `openssl`(1ssl) | calcola message digest con "`openssl dgst`" (OpenSSL)
`libsecret-tools` | V:0, I:9 | 49 | `secret-tool`(1) | archivia e recupera password (CLI)
`seahorse` | V:81, I:273 | 7971 | `seahorse`(1) | strumento di gestione delle chiavi (GNOME)

Vedere Sezione 9.9, «Suggerimenti per la cifratura dei dati» su dm-crypt e fscrypt che implementano un'infrastruttura di cifratura automatica dei dati usando moduli del kernel Linux.

### 10.3.1. Gestione delle chiavi per GnuPG

Quelli che seguono sono alcuni comandi per GNU Privacy Guard per la gestione base delle chiavi.

Tabella 10.7. Elenco di comandi per GNU Privacy Guard per la gestione delle chiavi

comando | descrizione
--- | ---
`gpg --gen-key` | Genera una nuova chiave
`gpg --gen-revoke mio_ID_utente` | genera una chiave di revoca per mio_ID_utente
`gpg --edit-key user_ID` | modifica la chiave in modo interattivo, "help" per l'aiuto
`gpg -o file --export` | export all public keys to file
`gpg -o file --export-secret-keys` | export all private key to file
`gpg --import file` | importa tutte le chiavi da un file
`gpg --send-keys ID_utente` | invia la chiave di ID_utente al server di chiavi
`gpg --recv-keys ID_utente` | riceve la chiave di ID_utente dal server di chiavi
`gpg --list-keys ID_utente` | elenca le chiavi di ID_utente
`gpg --list-sigs ID_utente` | elenca le firme di ID_utente
`gpg --check-sigs ID_utente` | controlla le firme di ID_utente
`gpg --fingerprint ID_utente` | controlla le impronte digitali di ID_utente
`gpg --refresh-keys` | aggiorna il portachiavi locale

Quelli seguenti sono i significati dei codici di fiducia.

Tabella 10.8. Elenco dei significati dei codici di fiducia

codice | descrizione della fiducia
--- | ---
`-` | nessuna fiducia assegnata dal proprietario / ancora non calcolata
`e` | calcolo della fiducia fallito
`q` | informazioni insufficienti per il calcolo
`n` | non fidarsi mai di questa chiave
`m` | marginalmente affidabile
`f` | completamente fidata
`u` | definitivamente fidata

The following generates my key "`9563FC29932C409F1A77F9C1AB8A1522D8234C6A`".

    $ gpg --gen-key
    gpg (GnuPG) 2.4.7; Copyright (C) 2024 g10 Code GmbH
    ...
    GnuPG needs to construct a user ID to identify your key.

    Real name: Osamu Aoki
    Email address: osamu@debian.org
    You selected this USER-ID:
        "Osamu Aoki <osamu@debian.org>"

    Change (N)ame, (E)mail, or (O)kay/(Q)uit? o
    ...
    public and secret key created and signed.

    pub   ed25519 2026-02-14 [SC] [expires: 2029-02-13]
          9563FC29932C409F1A77F9C1AB8A1522D8234C6A
    uid                      Osamu Aoki <osamu@debian.org>
    sub   cv25519 2026-02-14 [E] [expires: 2029-02-13]

Il comando seguente carica la mia chiave "`9563FC29932C409F1A77F9C1AB8A1522D8234C6A`" sul popolare server di chiavi "`hkp://keys.gnupg.net`".

    $ gpg --keyserver hkp://keys.gnupg.net --send-keys 9563FC29932C409F1A77F9C1AB8A1522D8234C6A

Un buon server di chiavi predefinito impostato in "`~/.gnupg/gpg.conf`" (o nella vecchia posizione "`~/.gnupg/options`") si ottiene la voce seguente.

    keyserver hkp://keys.gnupg.net

Il comando seguente recupera le chiavi sconosciute dal server di chiavi.

    $ gpg --list-sigs --with-colons | grep '^sig.*\[User ID not found\]' |\
              cut -d ':' -f 5| sort | uniq | xargs gpg --recv-keys

In OpenPGP Public Key Server (versioni pre-0.9.6) esisteva un bug che corrompeva le chiavi con più di 2 sottochiavi. I pacchetti `GnuPG` più recenti (>1.2.1-2) possono gestire queste sottochiavi corrotte. Vedere l'opzione "`--repair-pks-subkey-bug` in `gpg`(1).

Use of SHA-1 for hash has been deprecated. If your old RSA based openPGP key uses SHA-1 for hash, fix it using FixKeyWithSha1.

| Suggerimento
The `sq`(1) and `sqv`(1) commands are an alternative set of openPGP commands. See sq user documentation and A Practical Introduction to using sq, Sequoia PGP’s CLI.

### 10.3.2. Usare GnuPG su file

Quelli seguenti sono esempi di comandi per usare GNU Privacy Guard su file.

Tabella 10.9. Elenco di comandi GNU Privacy Guard per file

comando | descrizione
--- | ---
`gpg -a -s file` | firma un file in file.asc con corazza ASCII
`gpg --armor --sign file` | " "
`gpg --clearsign file` | inserisce una firma leggibile nel messaggio
`gpg --clearsign file|mail pippo@example.org` | invia un messaggio di posta firmato leggibile a `pippo@example.org`
`gpg --clearsign --not-dash-escaped patchfile` | inserisce una firma leggibile in patchfile
`gpg --verify file` | verifica un file con firma leggibile
`gpg -o file.sig -b file` | crea una firma staccata
`gpg -o file.sig --detach-sign file` | " "
`gpg --verify file.sig file` | verifica file con file.sig
`gpg -o cifr_file.gpg -r nome -e file` | cifratura di file nel file binario cifr_file.gpg usando la chiave pubblica indirizzata a nome
`gpg -o cifr_file.gpg --recipient nome --encrypt file` | " "
`gpg -o cifr_file.asc -a -r nome -e file` | cifratura di file nel file con cifratura corazzata ASCII cifr_file.asc usando la chiave pubblica indirizzata a nome
`gpg -o cifr_file.gpg -c file` | cifratura simmetrica da file a cifr_file.gpg
`gpg -o cifr_file.gpg --symmetric file` | " "
`gpg -o cifr_file.asc -a -c file` | cifratura simmetrica pensata per nome di file nel file con cifratura corazzata ASCII cifr_file.asc
`gpg -o file -d cifr_file.gpg -r nome` | decifratura
`gpg -o file --decrypt cifr_file.gpg` | " "

### 10.3.3. Usare GnuPG con Mutt

Aggiungere quanto seguie al file "`~/.muttrc`" per evitare che il lento GnuPG venga avviato automaticamente, permettendo allo stesso tempo di richiamarlo digitando "`S`" nel menu della vista indice.

    macro index S ":toggle pgp_verify_sig\n"
    set pgp_verify_sig=no

### 10.3.4. Usare GnuPG con Vim

Il plugin `gnupg` permette di eseguire GnuPG in modo trasparente per i file con estensione "`.gpg`", "`.asc`" e "`.pgp`".[6]

    $ sudo aptitude install vim-scripts
    $ echo "packadd! gnupg" >> ~/.vim/vimrc

### 10.3.5. Somme di controllo MD5

`md5sum`(1) fornisce un'utilità per creare un file digest usando il metodo descritto nella rfc1321 e per verificare i file con esso.

    $ md5sum foo bar >baz.md5
    $ cat baz.md5
    d3b07384d113edec49eaa6238ad5ff00  foo
    c157a79031e1c40f85931829bc5fc552  bar
    $ md5sum -c baz.md5
    foo: OK
    bar: OK

| Nota
Il calcolo delle somme di controllo MD5 è meno dispendioso in termini di CPU di quello delle firme crittografiche di GNU Privacy Guard (GnuPG). Di solito solamente il file digest di più alto livello è firmato crittograficamente per assicurare l'integrità dei dati.

### 10.3.6. Portachiavi per le password

Nei sistemi GNOME lo strumento GUI `seahorse`(1) gestisce le password e le archivia in modo sicuro nel portachiavi `~/.local/share/keyrings/*`.

`secret-tool`(1) può archiviare le password nel portachiavi dalla riga di comando.

Memorizziamo le passphrase usate per l'immagine del disco cifrata con LUKS/dm-crypt

    $ secret-tool store --label='LUKS passphrase for disk.img' LUKS my_disk.img
    Password: ********

Questa password archiviata può essere recuperata e passata ad altri programmi, es. `cryptsetup`(8).

    $ secret-tool lookup LUKS my_disk.img | \
      cryptsetup open disk.img disk_img --type luks --keyring -
    $ sudo mount /dev/mapper/disk_img /mnt

| Suggerimento
Ogni qual volta si deve fornire la password in uno script, usare `secret-tool` ed evitare di inserire direttamente nel codice la password.

## 10.4. Strumenti per la fusione di codice sorgente

Esistono molti strumenti per la fusione di codice sorgente. Quello che segue è un elenco di strumenti che hanno catturato la mia attenzione.

Tabella 10.10. Elenco di strumenti per la fusione di codice sorgente

pacchetto | popcon | dimensione | comando | descrizione
--- | --- | --- | --- | ---
`patch` | V:97, I:712 | 242 | `patch`(1) | applica un file diff ad un originale
`vim` | V:86, I:346 | 4089 | `vimdiff`(1) | confronta 2 file uno di fianco all'altro in vim
`imediff` | V:0, I:0 | 348 | `imediff`(1) | strumento interattivo a tutto schermo per unione di modifiche a 2/3 vie
`meld` | V:5, I:25 | 3546 | `meld`(1) | confronta e fonde file (GTK)
`wiggle` | V:0, I:0 | 175 | `wiggle`(1) | applica le patch respinte
`diffutils` | V:875, I:998 | 1768 | `diff`(1) | confronta i file riga per riga
`diffutils` | V:875, I:998 | 1768 | `diff3`(1) | confronta e fonde tre file riga per riga
`quilt` | V:1, I:18 | 880 | `quilt`(1) | gestisce serie di patch
`wdiff` | V:6, I:42 | 651 | `wdiff`(1) | mostra le differenze di parole tra file di testo
`diffstat` | V:10, I:104 | 79 | `diffstat`(1) | produce un istogramma delle modifiche apportate da un diff
`patchutils` | V:13, I:103 | 242 | `combinediff`(1) | crea una patch cumulativa da due patch incrementali
`patchutils` | V:13, I:103 | 242 | `dehtmldiff`(1) | estrae un diff da una pagina HTML
`patchutils` | V:13, I:103 | 242 | `filterdiff`(1) | estrae o esclude diff da un file diff
`patchutils` | V:13, I:103 | 242 | `fixcvsdiff`(1) | aggiusta file diff creati da CVS che sono male interpretati da `patch`(1)
`patchutils` | V:13, I:103 | 242 | `flipdiff`(1) | scambia l'ordine di due patch
`patchutils` | V:13, I:103 | 242 | `grepdiff`(1) | mostra quali file siano modificati da una patch che fa corrispondenza con un'espressione regolare
`patchutils` | V:13, I:103 | 242 | `interdiff`(1) | mostra le differenze tra due file diff unificati
`patchutils` | V:13, I:103 | 242 | `lsdiff`(1) | mostra quali file vengano modificati da una patch
`patchutils` | V:13, I:103 | 242 | `recountdiff`(1) | ricalcola conteggi e offset in diff unificati
`patchutils` | V:13, I:103 | 242 | `rediff`(1) | aggiusta conteggi ed offset di un diff modificato a mano
`patchutils` | V:13, I:103 | 242 | `splitdiff`(1) | separa due patch incrementali
`patchutils` | V:13, I:103 | 242 | `unwrapdiff`(1) | ripristina patch il cui contenuto è stato mandato a capo automaticamente
`dirdiff` | V:0, I:1 | 167 | `dirdiff`(1) | mostra le differenze ed apporta i cambiamenti tra alberi di directory
`docdiff` | V:0, I:0 | 554 | `docdiff`(1) | confronta due file parola per parola / carattere per carattere
`makepatch` | V:0, I:0 | 99 | `makepatch`(1) | genera file patch estesi
`makepatch` | V:0, I:0 | 99 | `applypatch`(1) | applica file patch estesi

### 10.4.1. Estrarre differenze da file sorgenti

Si possono estrarre le differenze tra due file sorgenti e creare file diff unificati "`file.patch0`" o "`file.patch1`", a seconda della posizione del file, con le procedure seguenti.

    $ diff -u file.old file.new > file.patch0
    $ diff -u old/file new/file > file.patch1

### 10.4.2. Fondere aggiornamenti per file sorgenti

I file diff (chiamati anche file patch) sono usati per inviare aggiornamenti per un programma. Chi li riceve applica questo aggiornamento ad un altro file nel modo seguente.

    $ patch -p0 file < file.patch0
    $ patch -p1 file < file.patch1

### 10.4.3. Unione (merge) interattiva

Se si hanno due versioni di un codice sorgente, è possibile effettuare una unione a 2 vie interattiva usando `imediff`(1) nel modo seguente.

    $ imediff -o file.merged file.old file.new

Se si hanno tre versioni di un codice sorgente, è possibile effettuare una unione a 3 vie interattiva usando `imediff`(1) nel modo seguente.

    $ imediff -o file.merged file.yours file.base file.theirs

## 10.5. Git

Git oggi giorno è lo strumento più usato per il sistema di controllo di versione(VCS) dato che Git può fare tutto per la gestione del codice sia locale che remota.

Debian fornisce servizi Git liberi attraverso il servizio Debian Salsa. La sua documentazione è reperibile su https://wiki.debian.org/Salsa.

Ecco alcuni pacchetti correlati a Git.

Tabella 10.11. Elenco di pacchetti e comandi relativi a Git

pacchetto | popcon | dimensione | comando | descrizione
--- | --- | --- | --- | ---
`git` | V:382, I:597 | 50172 | `git`(7) | Git, il sistema di controllo delle revisioni veloce, scalabile e distribuito
`gitk` | V:4, I:29 | 2003 | `gitk`(1) | browser degli archivi Git con interfaccia utente grafica e cronologia
`git-gui` | V:1, I:18 | 2508 | `git-gui`(1) | interfaccia utente grafica per Git (senza cronologia)
`git-email` | V:0, I:10 | 1187 | `git-send-email`(1) | invia una raccolta di patch come messaggio di posta da Git
`git-buildpackage` | V:1, I:7 | 2030 | `git-buildpackage`(1) | automatizza la creazione di pacchetti Debian con Git
`dgit` | V:0, I:1 | 724 | `dgit`(1) | interoperabilità di git con l'archivio Debian
`imediff` | V:0, I:0 | 348 | `git-ime`(1) | strumento ausialiario per aiutare a suddividere commit di git
`stgit` | V:0, I:0 | 604 | `stg`(1) | quilt sopra a git (Python)
`git-doc` | I:11 | 14238 | N/D | documentazione ufficiale per Git
`gitmagic` | I:0 | 721 | N/D | "Git Magic", una guida per Git più semplice da capire

### 10.5.1. Configurazione del client Git

È possibile che si desideri impostare diverse configurazioni globali, come il nome e l'indirizzo di posta elettronica usati da Git, in "`~/.gitconfig`" nel modo seguente.

    $ git config --global user.name "Name Surname"
    $ git config --global user.email yourname@example.com

Si può anche personalizzare il comportamento predefinito di Git nel modo seguente.

    $ git config --global init.defaultBranch main
    $ git config --global pull.rebase true
    $ git config --global push.default current

Se si è abituati ai comandi di CVS o Subversion, si potrebbe volere impostare alcuni alias per i comandi nel modo seguente.

    $ git config --global alias.ci "commit -a"
    $ git config --global alias.co checkout

La configurazione globale può essere controllata con il comando seguente.

    $ git config --global --list

### 10.5.2. Comandi Git di base

Il funzionamento di Git coinvolge diversi dati.

- L'albero di lavoro che contiene i file che l'utente vede e ai quali fa le modifiche.

  - Le modifiche da registrare devono essere selezionate esplicitamente e posizionate in attesa nell'indice. Questo viene fatto con i comandi `git add` e `git rm`.

- L'indice che contiene i file pronti per il commit (staged).

  - Il commit nel repository locale dei file preparati nell'indice (staged) verrà fatto alla successiva richiesta. Ciò viene fatto con il comando `git commit`.

- Il repository locale che contiene i file di cui è stato fatto il commit.

  - Git registra la cronologia collegata dei dati di cui è fatto il commit e li organizza come rami nel repository.

  - Il repository locale può inviare dati al repository remoto con il comando `git push`.

  - Il repository locale può ricevere dati dal repository remoto con i comandi `git fetch` e `git pull`.

    - Il comando `git pull` effettua un comando `git merge` o `git rebase` dopo il comando `git fetch`.

    - Qui, `git merge` combina due rami separati della cronologia per finire in un unico punto. (Questo è il comportamento predefinito di `git pull` senza alcuna personalizzazione e può essere buono per le persone che lavorano a monte che pubblicano rami verso molte persone.)

    - Qui, `git rebase` crea un singolo ramo di cronologia in sequenza del ramo remoto seguita da quella del ramo locale. (Questo è il caso della personalizzazione `pull.rebase true` e può essere adatto per il resto delle persone.)

- Il repository remoto che contiene i file di cui è stato fatto il commit.

  - La comunicazione con il repository remoto utilizza protocolli di comunicazione sicuri, come SSH o HTTPS.

L'albero di lavoro è fuori dalla directory `.git/`. I file dentro alla directory `.git/` contengono l'indice, i dati del repository locale e alcuni file di testo di configurazione di git.

Ecco una panoramica dei principali comandi di Git.

Tabella 10.12. Principali comandi Git

Comando Git | funzione
--- | ---
`git init` | creazione dell'archivio (locale)
`git clone URL` | clona il repository remoto in un repository locale con l'albero di lavoro
`git pull origin main` | aggiorna il ramo `main` locale in base al repository remoto `origin`
`git add .` | aggiunge il/i file nell'albero di lavoro all'indice solo per i file già presenti nell'indice
`git add -A .` | aggiunge il/i file nell'albero di lavoro all'indice per tutti i file, incluse le rimozioni
`git rm nomefile` | rimuove il/i file dall'albero di lavoro e dall'indice
`git commit` | fa il commit dei cambiamenti in attesa nell'indice nel repository locale
`git commit -a` | aggiunge tutte le modifiche all'albero di lavoro nell'indice e ne fa il commit nel repository locale (add + commit)
`git push -u origin nome_ramo` | aggiorna il repository remoto `origin` con il ramo locale `nome_ramo` (invocazione iniziale)
`git push origin nome_ramo` | aggiorna il repository remoto `origin` con il ramo locale `nome_ramo` (invocazione successiva)
`git diff treeish1 treeish2` | mostra le differenza tra il commit treeish1 e il commit treeish2
`gitk` | visualizzazione GUI dell'albero della cronologia dei rami del repository

### 10.5.3. Suggerimenti per Git

Ecco alcuni suggerimenti per Git.

Tabella 10.13. Suggerimenti per Git

Riga di comando di Git | funzione
--- | ---
`gitk --all` | per vedere la cronologia completa di Git e operare su di essa, come reimpostare HEAD ad un altro commit, scegliere una a una le patch, creare etichette e rami...
`git stash` | ottenere un albero di lavoro pulito senza perdere dati
`git remote -v` | controllare le impostazioni per il repository remoto
`git branch -vv` | controllare le impostazioni per il ramo
`git status` | mostrare lo stato dell'albero di lavoro
`git config -l` | elencare le impostazioni di Git
`git reset --hard HEAD; git clean -x -d -f` | annullare tutte le modifiche all'albero di lavoro e ripulirle completamente
`git rm --cached nomefile` | annullare l'indice con modifiche in stage cambiato con `git add nomefile`
`git reflog` | ottenere il registro dei riferimenti (utile per ripristinare commit da un ramo rimosso)
`git branch nome_nuovo_ramo HEAD@{6}` | crea un nuovo ramo dalle informazioni reflog
`git remote add nuovo_remoto URL` | aggiunge un repository remoto `nuovo_remoto` a cui punta l'URL
`git remote rename origin upstream` | rinomina il repository remoto da `origin` a `upstream`
`git branch -u upstream/nome_ramo` | imposta il tracciamento remoto al repository remoto `upstream` e al suo ramo `nome_ramo`.
`git remote set-url origin https://pippo/pluto.git` | cambia l'URL di `origin`
`git remote set-url --push upstream DISABLED` | disabilita il push verso `upstream` (Modificare `.git/config` per riabilitarlo)
`git remote update upstream` | prende gli aggiornamenti di tutti i rami remoti nel repository `upstream`
`git fetch upstream foo:upstream-foo` | crea un ramo locale (possibilmente orfano) `upstream-foo` come copia del ramo `foo` nel repository `upstream`
`git checkout -b ramo_topic ; git push -u ramo_topic origin` | crea un nuovo `ramo_topic` e ne fa il push verso `origin`
`git branch -m vecchionome nuovonome` | rinomina il nome locale del ramo
`git push -d origin ramo_da_rimuovere` | rimuove il ramo remoto (nuovo metodo)
`git push origin :ramo_da_rimuovere` | rimuove il ramo remoto (vecchio metodo)
`git checkout --orphan unconnected` | crea un nuovo ramo `unconnected`
`git rebase -i origin/main` | riordina/abbandona/fa lo squish dei commit da `origin/main` per ripulire la cronologia del ramo
`git reset HEAD^; git commit --amend` | schiaccia gli ultimi 2 commit in uno solo
`git checkout ramo_topic ; git merge --squash ramo_topic` | schiaccia l'intero `ramo_topic` in un commit
`git fetch --unshallow --update-head-ok origin '+refs/heads/*:refs/heads/*'` | converte un clone shallow in un clone completo di tutti i rami
`git ime` | suddivide l'ultimo commit in una serie di commit più piccoli file-per-file (è richiesto il pacchetto `imediff`)
`git repack -a -d; git prune` | reimpacchetta il repository locale in un singolo pacchetto (ciò può limitare la possibilità di ripristinare dati persi da rami cancellati, ecc.)

| Avvertimento
Non usare stringhe per etichette contenenti spazi, anche se alcuni strumenti come `gitk`(1) lo permettono. Altri comandi `git` potrebbero avere problemi con esse.

| Attenzione
Se viene fatto il rebase o lo squash di un ramo locale di cui è stato fatto il push sul repository remoto, fare il push di tale ramo ha rischi e richiede l'opzione `--force`. Solitamente ciò non è accettabile per il ramo `main` ma può essere accettabile per un ramo di specifico argomento prima dell'unione nel ramo `main`.

| Attenzione
A partire dall'inizio del 2006, l'invocazione diretta, dalla riga di comando, di un sottocomando di `git` come "`git-xyz`" è diventata deprecata.

| Suggerimento
Se c'è un file eseguibile `git-pippo` nel percorso specificato da `$PATH`, l'inserimento nella riga di comando di "`git pippo`" senza trattino invoca tale `git-pippo`. Questa è una funzionalità del comando `git`.

### 10.5.4. Documenti di consultazione per Git

Vedere la documentazione seguente.

- pagina man: git(1) (`/usr/share/doc/git-doc/git.html`)

- Manuale utente di Git (`/usr/share/doc/git-doc/user-manual.html`)

- Un tutorial introduttivo su git (`/usr/share/doc/git-doc/gittutorial.html`)

- Un tutorial introduttivo su git: parte seconda (`/usr/share/doc/git-doc/gittutorial-2.html`)

- Uso quotidiano di GIT con 20 comandi o poco più (`/usr/share/doc/git-doc/giteveryday.html`)

- Git Magic (`/usr/share/doc/gitmagic/html/index.html`)

### 10.5.5. Altri sistemi di controllo delle versioni

Un sistema di controllo delle versioni (VCS) è a volte noto come sistema di controllo delle revisioni (RCS) o gestione delle configurazione del software (SCM).

Ecco un riassunto degli altri VCS diversi da Git nel sistema Debian degni di nota.

Tabella 10.14. Elenco di altri strumenti per sistemi di controllo delle versioni

pacchetto | popcon | dimensione | strumento | tipo di VCS | commento
--- | --- | --- | --- | --- | ---
`mercurial` | V:3, I:26 | 2579 | Mercurial | distribuito | DVCS in Python e un po' di C
`darcs` | V:0, I:3 | 38784 | Darcs | distribuito | DVCS con algebra intelligente per le patch (lento)
`bzr` | I:4 | 28 | GNU Bazaar | distribuito | DVCS influenzato da `tla`, scritto in Python (storico)
`tla` | V:0, I:0 | 1022 | GNU arch | distribuito | DVCS principalmente da Tom Lord (storico)
`subversion` | V:10, I:59 | 4849 | Subversion | remoto | "CVS fatto bene", un più nuovo standard per VCS remoto (storico)
`cvs` | V:3, I:26 | 4835 | CVS | remoto | precedente standard per VCS remoto (storico)
`tkcvs` | V:0, I:0 | 34 | CVS, … | remoto | visualizzazione GUI di alberi di archivi VCS (CVS, Subversion, RCS)
`rcs` | V:1, I:9 | 578 | RCS | locale | "SCCS Unix fatto bene" (storico)
`cssc` | V:0, I:0 | 2044 | CSSC | locale | clone di SCCS Unix (storico)

[4] Supporti scrivibili una sola volta, come CD/DVD-R possono prevenire incidenti di sovrascrittura. (Vedere Sezione 9.8, «I dati binari» per come scrivere sul supporto di archiviazione dalla riga di comando della shell. L'ambiente desktop GNOME con interfaccia grafica fornisce un facile accesso tramite menu: "Risorse→Creazione CD/DVD".)

[5] Alcuni di questi dati non possono essere rigenerati inserendo la stessa stringa di input nel sistema.

[6] Se si usa "`~/.vimrc`" invece di "`~/.vim/vimrc`", modificare di conseguenza.

Capitolo 9. Suggerimenti per il sistema |  | Capitolo 11. Conversione di dati