Prima di leggere: prova a rispondere
Nella lezione sui comandi fondamentali hai scoperto quale programma risponde quando scrivi
ls, e lo hai scoperto chiedendolo al gestore dei pacchetti. Adesso tre domande sul
gestore stesso. Quanti pacchetti sono installati sulla tua macchina? Di quelli, quanti li hai chiesti
tu e quanti sono arrivati come dipendenze? E quando rimuovi un pacchetto, che cosa resta sul disco?
La terza è quella che fa la differenza fra una macchina pulita e una macchina che accumula. Scrivi le tre risposte, anche a sentimento: alla fine della lezione le confronterai con tre numeri misurati sulla tua macchina.
Il problema: un comando che non c'è, e una macchina che non sai com'è fatta
I due problemi che un gestore di pacchetti risolve sembrano uno. Il primo è installare: ti serve un programma, lo chiedi, arriva. È la parte facile, e si impara con due comandi.
Il secondo è sapere com'è fatta la macchina su cui stai lavorando, e qui il gestore di pacchetti è la fonte più autorevole che hai: quale programma possiede un file, da quale repository è arrivato un pacchetto, quale versione, se è stato modificato, chi dipende da chi. Su un server che non hai installato tu, queste risposte valgono più di qualsiasi documentazione, perché le dà il sistema e non una persona che ricorda.
La parte che quasi nessuno impara è che su Debian e Ubuntu i programmi sono due, impilati, e rispondono a domande diverse. Confonderli porta a cercare l'informazione con lo strumento sbagliato e a concludere che non c'è.
Due programmi, due livelli
dpkg installa, rimuove e interroga i pacchetti che hai già in mano. Non
sa che esista una rete, non risolve dipendenze, non sa dove scaricare niente: sa trattare un file e
sa tutto di quelli installati. apt sta sopra: conosce i repository, risolve le
dipendenze, scarica, e poi chiama dpkg per fare il lavoro.
$ apt --version
apt 3.2.0 (amd64)
$ dpkg --version
Debian "dpkg", programma di gestione dei pacchetti versione 1.23.7 (amd64).
Da questa divisione segue una regola che risolve metà dei dubbi: se la tua domanda riguarda lo stato
della macchina, lo strumento è dpkg oppure dpkg-query. Se riguarda che cosa
potrebbe essere installato, da dove, e in quale versione, lo strumento è apt.
Lo stato di un pacchetto è di due lettere, non di una
La domanda «il pacchetto è installato» ha più di due risposte, e questo spiega la terza domanda
d'apertura. dpkg tiene per ogni pacchetto uno stato desiderato e uno stato effettivo, e
li riporta come due lettere. Misurato su questa macchina il 2026-10-30:
$ dpkg-query -f '${db:Status-Abbrev}\n' -W | sort | uniq -c | sort -rn
2766 ii
50 rc
Duemilasettecentosessantasei pacchetti in stato ii, cioè voluti e installati. E
cinquanta in stato rc: la r significa che sono stati rimossi, la
c significa che i loro file di configurazione sono ancora sul disco.
Sono i residui di apt remove, che toglie i programmi e lascia la configurazione,
pensando che un giorno potresti reinstallare.
$ dpkg-query -f '${db:Status-Abbrev} ${binary:Package}\n' -W | grep '^rc' | head -5
rc docker-desktop
rc gnome-shell-extension-desktop-icons-ng
rc keyboxd
rc libgvc6
rc linux-image-6.14.0-34-generic
Il comando che non lascia residui è apt purge, e la differenza con remove
non è un dettaglio di pulizia: un file di configurazione residuo viene ritrovato se reinstalli il
pacchetto, quindi un pacchetto reinstallato per risolvere un problema di configurazione
ritrova la configurazione che aveva il problema. È il motivo per cui
«disinstalla e reinstalla» a volte non cambia niente.
Chi ha chiesto che cosa
apt ricorda quali pacchetti hai chiesto tu e quali sono arrivati come dipendenza, e la
distinzione serve: quando nessuno dipende più da un pacchetto automatico, può essere rimosso.
Misurato:
$ apt-mark showmanual | wc -l
183
$ apt-mark showauto | wc -l
2583
Centottantatré richiesti, duemilacinquecentottantatré arrivati per conseguenza. Il rapporto sorprende la prima volta, e spiega perché l'elenco di quello che hai installato non è l'elenco di quello che c'è: per ogni programma che chiedi, in media sulla mia macchina ne arrivano quattordici.
Esempio svolto: da dove arriverebbe questo pacchetto
Il problema: devi installare uno strumento su un server e vuoi sapere, prima di farlo, quale versione arriverebbe e da quale fonte. Su un sistema in produzione la provenienza conta, perché un pacchetto da un repository aggiuntivo ha un ciclo di aggiornamento diverso da quello della distribuzione.
L'informazione disponibile: apt-cache policy su un nome di pacchetto risponde con la
versione installata, la candidata, e l'elenco delle fonti con la loro priorità. Il ragionamento: se
vedo la priorità, so anche quale fonte vincerebbe in caso di conflitto, e questo è il dato che
serve davvero.
$ apt-cache policy nftables
nftables:
Installato: 1.1.6-1
Candidato: 1.1.6-1
Tabella versione:
*** 1.1.6-1 500
500 http://archive.ubuntu.com/ubuntu resolute/main amd64 Packages
100 /var/lib/dpkg/status
$ apt-cache policy traceroute
traceroute:
Installato: (nessuno)
Candidato: 1:2.1.6-1build1
Tabella versione:
1:2.1.6-1build1 500
500 http://archive.ubuntu.com/ubuntu resolute/universe amd64 Packages
Nel primo caso i tre asterischi marcano la versione installata, che coincide con la candidata, quindi
non c'è niente da aggiornare. Il 500 è la priorità della fonte e il 100 è
quella dello stato locale: il numero più alto vince, ed è per questo che una versione disponibile in
un repository prevale su quella installata.
Nel secondo caso Installato: (nessuno) conferma quello che avevo misurato nella lezione
sulla diagnostica di rete, e aggiunge il dato che lì mancava: il pacchetto esiste, la versione
candidata è 1:2.1.6-1build1, e arriva da universe e non da
main. La differenza fra i due archivi riguarda il livello di supporto, e su un server
vale la pena saperlo prima di dipendere da quel pacchetto.
La decisione che prendo: prima di installare qualcosa su una macchina che conta, eseguo
apt-cache policy e poi la simulazione. L'alternativa che ho scartato è
installare e vedere: il problema non è l'installazione, è che apt per soddisfare una
dipendenza può rimuovere qualcosa, e su un server è esattamente la cosa che non vuoi scoprire dopo.
$ apt-get -s autoremove
I seguenti pacchetti saranno RIMOSSI:
nvidia-firmware-595-595.91.07
0 aggiornati, 0 installati, 1 da rimuovere e 22 non aggiornati.
Remv nvidia-firmware-595-595.91.07 [595.91.07-0ubuntu0.26.04.1]
L'opzione -s simula: calcola tutto, stampa il piano, e non scrive niente. La verifica
che ne ricavo è l'elenco esatto di che cosa verrebbe rimosso, con la versione. L'errore che avrei
potuto commettere, e che ho visto commettere su un server, è eseguire autoremove senza
simulare: il comando è pensato per togliere ciò che non serve più, e se un pacchetto era stato
marcato come automatico per errore lo porta via insieme agli altri.
Il caso negativo: una domanda a cui lo strumento risponde «non lo so»
Vuoi sapere quale pacchetto possiede il programma nft, che hai usato nella lezione sul
firewall. Scrivi il comando e ottieni questo. Prima di leggere il seguito, dimmi se la risposta
significa che il file non appartiene a nessun pacchetto.
$ dpkg -S /usr/bin/nft
dpkg-query: nessun percorso corrispondente a /usr/bin/nft
$ dpkg -S /usr/sbin/nft
nftables: /usr/sbin/nft
La risposta non significa niente sul file: significa che quel percorso non è nel
registro. nft sta in /usr/sbin, non in /usr/bin, e
dpkg -S confronta le stringhe dei percorsi, non cerca il programma. Lo strumento
risponde esattamente alla domanda che gli hai fatto, e la domanda era sbagliata.
L'errore è plausibile perché su una macchina moderna /bin e /sbin sono
collegamenti verso /usr, come hai misurato nella prima lezione, e la distinzione fra
/usr/bin e /usr/sbin sopravvive mentre quella fra /bin e
/usr/bin è scomparsa: è facile concludere che tutto sia confluito in un posto solo.
La difesa è non scrivere il percorso a memoria: si ottiene con command -v, e si passa
quello.
Esiste però un caso in cui la risposta negativa è vera e informativa, e distinguerlo dal primo è la competenza che conta:
$ dpkg -S /etc/resolv.conf
dpkg-query: nessun percorso corrispondente a /etc/resolv.conf
Qui il percorso è giusto e il file esiste, come hai visto nella lezione sulla diagnostica. La
risposta negativa dice una cosa vera e utile: quel file non appartiene a nessun
pacchetto, cioè è stato creato dopo l'installazione, da un servizio o da una persona.
È esattamente l'informazione che cerchi quando devi capire se un file su un server è parte del
sistema o è stato messo lì da qualcuno. Il modo di distinguere i due casi è verificare prima che il
percorso sia quello vero, con command -v per i programmi o con ls per i
file.
Esercizio 1, guidato: tre numeri sulla tua macchina
Rispondi con un comando alle tre domande d'apertura: quanti pacchetti installati, quanti richiesti da te, e quanti con configurazione residua. Poi confronta con le tre previsioni che avevi scritto. Criterio: hai tre numeri e i tre comandi che li producono, e per il terzo numero hai anche l'elenco dei nomi.
Esercizio 2, autonomo: inventario di un server che non conosci
Scegli tre file di configurazione sotto /etc sulla tua macchina e, per ciascuno,
stabilisci se appartiene a un pacchetto, a quale, e se è stato modificato dopo l'installazione.
L'ultima parte richiede uno strumento che non è stato nominato in questa lezione: cercalo partendo
dal fatto che dpkg conserva una somma di controllo dei file che installa.
Criterio di successo: per ciascuno dei tre file hai il verdetto e il comando che lo produce, e per
almeno uno il verdetto è «modificato» oppure «non appartiene a nessun pacchetto».
Soluzioni commentate
Esercizio 1. I tre comandi sono dpkg-query -f '${binary:Package}\n' -W | wc
-l per il totale, apt-mark showmanual | wc -l per i richiesti, e
dpkg-query -f '${db:Status-Abbrev} ${binary:Package}\n' -W | grep '^rc' per i residui.
Sulla mia macchina i numeri sono 2816, 183 e 50.
Perché non dpkg -l | wc -l, che è la forma che si trova più spesso: quell'output ha
cinque righe di intestazione e una formattazione in colonne che tronca i nomi lunghi, quindi il
conteggio è sbagliato di cinque e i nomi non sono usabili. dpkg-query -f prende un
formato dichiarato da te e produce esattamente quello, che è la forma giusta quando l'output lo legge
un altro comando. È la stessa distinzione fra uscita per una persona e uscita per un programma che
hai visto con LC_ALL=C nella lezione sull'ambiente.
Sul terzo numero vale la pena guardare i nomi e non solo contarli. Nel mio elenco c'è
linux-image-6.14.0-34-generic, cioè un vecchio kernel rimosso che ha lasciato la sua
configurazione; e c'è docker-desktop, un programma che ho disinstallato e di cui resta
la configurazione. Il primo è innocuo, il secondo è il caso in cui una reinstallazione futura
ritroverebbe impostazioni vecchie. La ripulitura si fa con apt purge sui nomi in stato
rc, ed è una delle poche operazioni di manutenzione che vale la pena fare a mano.
Esercizio 2. Lo strumento è dpkg --verify, che confronta le somme di
controllo dei file installati con quelle registrate e riporta solo le differenze. La forma
dpkg --verify nomepacchetto lo limita a un pacchetto, e un'uscita vuota significa che
nessun file è stato modificato.
Due avvertenze sul risultato, perché senza queste il verdetto si legge male. La prima: non tutti i
file sono verificabili, perché dpkg registra le somme di controllo dei file ordinari e
non di quelli che il pacchetto si aspetta che cambino. La seconda, più importante: un file di
configurazione modificato legittimamente da te compare come differente, quindi
«differente» non significa «compromesso». Lo strumento risponde a «questo file è come lo ha
installato il pacchetto», che è una domanda utile e diversa.
Perché l'alternativa più ovvia è peggiore. Confrontare la data di modifica con la data dell'installazione sembra equivalente e non lo è: la data cambia anche se il contenuto no, per esempio dopo una riscrittura automatica identica, e non cambia se qualcuno ha modificato il file preservandola. La somma di controllo guarda il contenuto, che è la cosa a cui tieni.
Domande per fissare il concetto
Perché apt ha bisogno di dpkg mentre dpkg non ha bisogno di
apt, e che conseguenza ha questo su una macchina senza rete? Se un pacchetto ha
priorità 500 in due repository diversi, come si decide quale vince, e dove cercheresti la risposta?
E come spiegheresti a un collega la differenza fra remove e purge usando il
caso del programma reinstallato che ritrova il suo problema?
Che cosa adesso sai fare
Sai quale dei due programmi interrogare in base alla domanda che hai: lo stato della macchina a
dpkg, le possibilità e le fonti ad apt. Sai leggere lo stato di due lettere
di un pacchetto, e sai che rc significa configurazione residua e che è la ragione per
cui una reinstallazione a volte non risolve niente.
Sai simulare un'operazione prima di eseguirla, e sai perché su un server autoremove va
sempre simulato. Sai che dpkg -S confronta percorsi e non cerca programmi, e sai
distinguere una risposta negativa che dipende dalla tua domanda da una che dice qualcosa sul file.
La verifica concreta: scegli un programma che usi ogni giorno, trova il suo percorso con
command -v, e risali al pacchetto e alla fonte da cui è arrivato.