Product SiteDocumentation Site

5.4. Manipolazione dei pacchetti con dpkg

dpkg è il comando di base per gestire i pacchetti Debian sul sistema. Se si hanno dei pacchetti .deb, è dpkg che permette l'installazione o l'analisi del loro contenuto. Ma questo programma ha solo una visione parziale dell'universo Debian: conosce cosa è installato sul sistema e ciò che è dato sulla riga di comando, ma non conosce nulla degli altri pacchetti disponibili. Perciò, fallirà se una dipendenza non è soddisfatta. Strumenti come apt-get, al contrario, creano un elenco di dipendenze da installare il più automaticamente possibile.

5.4.1. Installazione dei pacchetti

dpkg è, soprattutto, uno strumento per installare un pacchetto Debian già disponibile (perché non scarica niente). Per fare ciò, si usa la sua opzione -i oppure --install.

Esempio 5.2. Installazione di un pacchetto con dpkg

# dpkg -i man-db_2.7.6.1-2_amd64.deb
(Reading database ... 110431 files and directories currently installed.)
Preparing to unpack man-db_2.7.6.1-2_amd64.deb ...
Unpacking man-db (2.7.6.1-2) over (2.7.6.1-1) ...
Setting up man-db (2.7.6.1-2) ...
Updating database of manual pages ...
Processing triggers for mime-support (3.60) ...
Si possono vedere i differenti passi eseguiti da dpkg; si può sapere, perciò, a quale punto si è verificato un errore. L'installazione può anche essere effettuata in due stadi: prima lo spacchettamento, poi la configurazione. apt-get si avvantaggia di ciò, limitando il numero di chiamate a dpkg (dal momento che ogni chiamata è onerosa a causa del caricamento del database in memoria, specialmente l'elenco dei file già installati).

Esempio 5.3. Spacchettamento e configurazione separati

# dpkg --unpack man-db_2.7.6.1-2_amd64.deb
(Reading database ... 110431 files and directories currently installed.)
Preparing to unpack man-db_2.7.6.1-2_amd64.deb ...
Unpacking man-db (2.7.6.1-2) over (2.7.6.1-2) ...
Processing triggers for mime-support (3.60) ...
# dpkg --configure man-db
Setting up man-db (2.7.6.1-2) ...
Updating database of manual pages ...
Talvolta dpkg non riuscirà a installare un pacchetto e restituirà un errore; se l'utente ordina di ignorarlo, verrà emesso soltanto un avvertimento; è per questo motivo che esistono le diverse opzioni --force-*. Il comando dpkg --force-help, o la documentazione di questo comando, dà un elenco completo di queste opzioni. L'errore più frequente, che prima o poi si incontrerà, è una collisione tra file. Quando un pacchetto contiene un file che è già installato da un altro pacchetto, dpkg si rifiuterà di installarlo. Il seguente messaggio apparirà:
Unpacking libisc52 (from .../libisc52_1%3a9.6.ESV.R1+dfsg-0+lenny2_amd64.deb) ...
dpkg : error processing /var/cache/apt/archives/libisc52_1%3a9.6.ESV.R1+dfsg-0+lenny2_amd64.deb (--unpack) :
 trying to overwrite "/usr/lib/libisc.so.50", which is also in package libisc50 1:9.6.1.dfsg.P1-3
In questo caso, se si pensa che sostituire questo file non sia un rischio significativo per la stabilità del sistema (e solitamente è così), si può usare l'opzione --force-overwrite, che dice a dpkg di ignorare questo errore e di sovrascrivere il file.
Anche se ci sono molte opzioni --force-*, è probabile che solo --force-overwrite sia usata regolarmente. Queste opzioni esistono solamente per situazioni eccezionali ed è meglio lasciarle stare il più possibile per rispettare le regole imposte dal meccanismo dei pacchetti. Non si dimentichi che queste regole assicurano la coerenza e la stabilità del sistema.

5.4.2. Rimozione di pacchetti

Invocare dpkg con l'opzione -r o --remove seguita dal nome del pacchetto, rimuove tale pacchetto. Questa rimozione, comunque, non è completa: rimangono tutti i file di configurazione e gli script, i file di registro (registri di sistema) e altri dati dell'utente gestiti dal pacchetto. La ragione della loro conservazione è di disabilitare il programma disinstallandolo, preservando allo stesso tempo l'opzione di reinstallarlo velocemente e con la stessa configurazione. Per rimuovere completamente ogni cosa associata al pacchetto, usare l'opzione -P o --purge seguita dal nome del pacchetto.

Esempio 5.4. Rimozione ed eliminazione completa del pacchetto debian-cd

# dpkg -r debian-cd
(Reading database ... 112188 files and directories currently installed.)
Removing debian-cd (3.1.20) ...
# dpkg -P debian-cd
(Reading database ... 111613 files and directories currently installed.)
Purging configuration files for debian-cd (3.1.20) ...

5.4.3. Interrogazione del Database di dpkg ed Ispezione dei File .deb

Prima di concludere questa sezione, si noti che alcune opzioni di dpkg possono interrogare il database interno per ottenere informazioni. Mostrando prima le opzioni lunghe e poi le corrispondenti opzioni corte (che evidentemente accettano i soliti argomenti) we cite --listfiles pacchetto (o -L), che elenca i file installati da questo pacchetto; --search file (o -S), che trova il pacchetto da cui proviene il file; --status pacchetto (o -s), che mostra le intestazioni di un pacchetto installato; --list (o -l), che mostra l'elenco dei pacchetti conosciuti dal sistema e il loro stato di installazione; --contents file.deb (o -c), che elenca i file nel pacchetto Debian specificato; --info file.deb (o -I), che mostra le intestazioni del pacchetto Debian.

Esempio 5.5. Varie richieste con dpkg

$ dpkg -L base-passwd
/.
/usr
/usr/sbin
/usr/sbin/update-passwd
/usr/share
/usr/share/base-passwd
/usr/share/base-passwd/group.master
/usr/share/base-passwd/passwd.master
/usr/share/doc
/usr/share/doc/base-passwd
/usr/share/doc/base-passwd/README
/usr/share/doc/base-passwd/changelog.gz
/usr/share/doc/base-passwd/copyright
/usr/share/doc/base-passwd/users-and-groups.html
/usr/share/doc/base-passwd/users-and-groups.txt.gz
/usr/share/doc-base
/usr/share/doc-base/users-and-groups
/usr/share/lintian
/usr/share/lintian/overrides
/usr/share/lintian/overrides/base-passwd
/usr/share/man
/usr/share/man/de
/usr/share/man/de/man8
/usr/share/man/de/man8/update-passwd.8.gz
/usr/share/man/es
/usr/share/man/es/man8
/usr/share/man/es/man8/update-passwd.8.gz
/usr/share/man/fr
/usr/share/man/fr/man8
/usr/share/man/fr/man8/update-passwd.8.gz
/usr/share/man/ja
/usr/share/man/ja/man8
/usr/share/man/ja/man8/update-passwd.8.gz
/usr/share/man/man8
/usr/share/man/man8/update-passwd.8.gz
/usr/share/man/pl
/usr/share/man/pl/man8
/usr/share/man/pl/man8/update-passwd.8.gz
/usr/share/man/ru
/usr/share/man/ru/man8
/usr/share/man/ru/man8/update-passwd.8.gz
$ dpkg -S /bin/date
coreutils: /bin/date
$ dpkg -s coreutils
Package: coreutils
Essential: yes
Status: install ok installed
Priority: required
Section: utils
Installed-Size: 15103
Maintainer: Michael Stone <mstone@debian.org>
Architecture: amd64
Multi-Arch: foreign
Version: 8.26-3
Replaces: mktemp, realpath, timeout
Pre-Depends: libacl1 (>= 2.2.51-8), libattr1 (>= 1:2.4.46-8), libc6 (>= 2.17), libselinux1 (>= 2.1.13)
Conflicts: timeout
Description: GNU core utilities
 This package contains the basic file, shell and text manipulation
 utilities which are expected to exist on every operating system.
 .
 Specifically, this package includes:
 arch base64 basename cat chcon chgrp chmod chown chroot cksum comm cp
 csplit cut date dd df dir dircolors dirname du echo env expand expr
 factor false flock fmt fold groups head hostid id install join link ln
 logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup nproc numfmt
 od paste pathchk pinky pr printenv printf ptx pwd readlink realpath rm
 rmdir runcon sha*sum seq shred sleep sort split stat stty sum sync tac
 tail tee test timeout touch tr true truncate tsort tty uname unexpand
 uniq unlink users vdir wc who whoami yes
Homepage: http://gnu.org/software/coreutils
$ dpkg -l 'b*'
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                 Version         Architecture    Description
+++-====================-===============-===============-=============================================
un  backupninja          <none>          <none>          (no description available)
un  backuppc             <none>          <none>          (no description available)
un  baekmuk-ttf          <none>          <none>          (no description available)
un  base                 <none>          <none>          (no description available)
un  base-config          <none>          <none>          (no description available)
ii  base-files           9.9+deb9u1      amd64           Debian base system miscellaneous files
ii  base-passwd          3.5.43          amd64           Debian base system master password and group 
ii  bash                 4.4-5           amd64           GNU Bourne Again SHell
[...]
$ dpkg -c /var/cache/apt/archives/gnupg_2.1.18-8~deb9u1_amd64.deb
drwxr-xr-x root/root         0 2017-09-18 20:41 ./
drwxr-xr-x root/root         0 2017-09-18 20:41 ./usr/
drwxr-xr-x root/root         0 2017-09-18 20:41 ./usr/bin/
-rwxr-xr-x root/root    996648 2017-09-18 20:41 ./usr/bin/gpg
-rwxr-xr-x root/root      3444 2017-09-18 20:41 ./usr/bin/gpg-zip
-rwxr-xr-x root/root    161192 2017-09-18 20:41 ./usr/bin/gpgconf
-rwxr-xr-x root/root     26696 2017-09-18 20:41 ./usr/bin/gpgparsemail
-rwxr-xr-x root/root     76112 2017-09-18 20:41 ./usr/bin/gpgsplit
-rwxr-xr-x root/root    158344 2017-09-18 20:41 ./usr/bin/kbxutil
-rwxr-xr-x root/root      1081 2014-06-25 16:17 ./usr/bin/lspgpot
-rwxr-xr-x root/root      2194 2017-09-18 20:41 ./usr/bin/migrate-pubring-from-classic-gpg
-rwxr-xr-x root/root     14328 2017-09-18 20:41 ./usr/bin/watchgnupg
drwxr-xr-x root/root         0 2017-09-18 20:41 ./usr/sbin/
-rwxr-xr-x root/root      3078 2017-09-18 20:41 ./usr/sbin/addgnupghome
-rwxr-xr-x root/root      2219 2017-09-18 20:41 ./usr/sbin/applygnupgdefaults
drwxr-xr-x root/root         0 2017-09-18 20:41 ./usr/share/
drwxr-xr-x root/root         0 2017-09-18 20:41 ./usr/share/doc/
drwxr-xr-x root/root         0 2017-09-18 20:41 ./usr/share/doc/gnupg/
-rw-r--r-- root/root     18964 2017-01-23 18:39 ./usr/share/doc/gnupg/DETAILS.gz
[...]
$ dpkg -I /var/cache/apt/archives/gnupg_2.1.18-8~deb9u1_amd64.deb
 new debian package, version 2.0.
 size 1124042 bytes: control archive=2221 bytes.
    1388 bytes,    24 lines      control              
    2764 bytes,    43 lines      md5sums              
 Package: gnupg
 Source: gnupg2
 Version: 2.1.18-8~deb9u1
 Architecture: amd64
 Maintainer: Debian GnuPG Maintainers <pkg-gnupg-maint@lists.alioth.debian.org>
 Installed-Size: 2088
 Depends: gnupg-agent (= 2.1.18-8~deb9u1), libassuan0 (>= 2.0.1), libbz2-1.0, libc6 (>= 2.15), libgcrypt20 (>= 1.7.0), libgpg-error0 (>= 1.14), libksba8 (>= 1.3.4), libreadline7 (>= 6.0), libsqlite3-0 (>= 3.7.15), zlib1g (>= 1:1.1.4)
 Recommends: dirmngr (= 2.1.18-8~deb9u1), gnupg-l10n (= 2.1.18-8~deb9u1)
 Suggests: parcimonie, xloadimage
 Breaks: debsig-verify (<< 0.15), dirmngr (<< 2.1.18-8~deb9u1), gnupg2 (<< 2.1.11-7+exp1), libgnupg-interface-perl (<< 0.52-3), libgnupg-perl (<= 0.19-1), libmail-gnupg-perl (<= 0.22-1), monkeysphere (<< 0.38~), php-crypt-gpg (<= 1.4.1-1), python-apt (<= 1.1.0~beta4), python-gnupg (<< 0.3.8-3), python3-apt (<= 1.1.0~beta4)
 Replaces: gnupg2 (<< 2.1.11-7+exp1)
 Provides: gpg
 Section: utils
 Priority: optional
 Multi-Arch: foreign
 Homepage: https://www.gnupg.org/
 Description: GNU privacy guard - a free PGP replacement
  GnuPG is GNU's tool for secure communication and data storage.
  It can be used to encrypt data and to create digital signatures.
  It includes an advanced key management facility and is compliant
  with the proposed OpenPGP Internet standard as described in RFC4880.
[...]

5.4.4. File di registro di dpkg

Una funzionalità introdotta recentemente in dpkg è che mantiene un registro di tutte le proprie azioni in /var/log/dpkg.log. Questo registro è estremamente prolisso, dal momento che contiene dettagli di ciascun stato attraverso cui passano i pacchetti gestiti da dpkg. Oltre a offrire un modo per tenere traccia del comportamento di dpkg, ciò aiuta, soprattutto, a mantenere una cronologia dello sviluppo del sistema: si può trovare il momento esatto in cui ciascun pacchetto è stato installato o aggiornato e queste informazioni possono essere estremamente utili nel comprendere un recente cambiamento di comportamento. Inoltre, siccome tutte le versioni sono registrate, è facile incrociare queste informazioni con il changelog.Debian.gz dei pacchetti in questione o anche con le segnalazioni di bug online.

5.4.5. Supporto Multi-Arch

Tutti i pacchetti Debian hanno un campo Architecture nelle loro informazioni di controllo. Questo campo può contenere tutti “all” (per i pacchetti indipendenti dalle architetture) oppure il nome dell'architettura per la quale è sviluppato il pacchetto (come “amd64”, “armhf”, …). In quest'ultimo caso, per impostazione predefinita, dpkg accetterà di installare il pacchetto solo se la sua architettura corrisponde a quella dell'host come restituito da dpkg --print-architecture.
Questa restrizione assicura che gli utenti non finiscano con binari compilati per un'architettura sbagliata. Tutto sarebbe perfetto, se non fosse che (alcuni) i computer possono eseguire binari per architetture multiple, sia nativamente (un sistema "amd64" può eseguire binari "i386") che attraverso emulatori.

5.4.5.1. Abilitazione Multi-Arch

Il supporto multi-arch di dpkg consente agli utenti di definire le "architetture esterne" che possono essere installate sul sistema corrente. Questo può essere fatto semplicemnete con dpkg --add-architecture come nell'esempio qui sotto. C'è un comando corrispondente per rimuovere il supporto ad un'architettura esterna che è dpkg --remove-architecture, ma può essere utilizzato solo quando non rimangono pacchetti di questa archietttura.
# dpkg --print-architecture
amd64
# dpkg --print-foreign-architectures
# dpkg -i gcc-6-base_6.3.0-18_armhf.deb
dpkg: error processing archive gcc-6-base_6.3.0-18_armhf.deb (--install):
 package architecture (armhf) does not match system (amd64)
Errors were encountered while processing:
 gcc-6-base_6.3.0-18_armhf.deb
# dpkg --add-architecture armhf
# dpkg --add-architecture armel
# dpkg --print-foreign-architectures
armhf
armel
# dpkg -i gcc-6-base_6.3.0-18_armhf.deb
Selecting previously unselected package gcc-6-base:armhf.
(Reading database ... 112000 files and directories currently installed.)
Preparing to unpack gcc-6-base_6.3.0-18_armhf.deb ...
Unpacking gcc-6-base:armhf (6.3.0-18) ...
Setting up gcc-6-base:armhf (6.3.0-18) ...
# dpkg --remove-architecture armhf
dpkg: error: cannot remove architecture 'armhf' currently in use by the database
# dpkg --remove-architecture armel
# dpkg --print-foreign-architectures
armhf

5.4.5.2. Variazioni Relative a Multi-Arch

To make multi-arch actually useful and usable, libraries had to be repackaged and moved to an architecture-specific directory so that multiple copies (targeting different architectures) can be installed alongside. Such updated packages contain the “Multi-Arch: same” header field to tell the packaging system that the various architectures of the package can be safely co-installed (and that those packages can only satisfy dependencies of packages of the same architecture). The most important libraries have been converted since the introduction of multi-arch in Debian Wheezy, but there are many libraries that will likely never be converted unless someone specifically requests it (through a bug report for example).
$ dpkg -s gcc-6-base
dpkg-query: error: --status needs a valid package name but 'gcc-6-base' is not: ambiguous package name 'gcc-6-base' with more than one installed instance

Use --help for help about querying packages.
$ dpkg -s gcc-6-base:amd64 gcc-6-base:armhf | grep ^Multi
Multi-Arch: same
Multi-Arch: same
$ dpkg -L libgcc1:amd64 |grep .so
/lib/x86_64-linux-gnu/libgcc_s.so.1
$ dpkg -S /usr/share/doc/gcc-6-base/copyright
gcc-6-base:amd64, gcc-6-base:armhf: /usr/share/doc/gcc-6-base/copyright
Vale la pena notare che i pacchetti Multi-Arch: same devono avere i nomi che identificano le loro architetture per essere identificati senza ambiguità. Essi hanno anche la possibilità di condividere i file con altre istanze dello stesso pacchetto; dpkg assicura che tutti i pacchetti abbiano dei file identici bit-per-bit quando sono condivisi. Infine, tutte le istanze di un pacchetto devono avere la stessa versione. Essi devono quindi essere aggiornati insieme.
Il supporto multi-Arch portacon sè anche alcune sfide interessanti nel modo in cui sono gestite le dipendenze. Soddisfare una dipendenza richiede o un pacchetto contrassegnato come “Multi-Arch: foreign” o un pacchetto la cui architettura corrisponde a quella del pacchetto del quale dichiara la dipendenza (in questo processo di risoluzione delle dipendenze, i pacchetti architettura-indipendenti si presume che siano della stessa architettura dell'host). Una dipendenza può anche essere indebolita per consentire a qualsiasi architettura di soddisfarla, con la sintassi package:any, ma i pacchetti esterni sono in grado di soddisfarla solo se sono contrassegnati come “Multi-Arch: allowed”.