Product SiteDocumentation Site

5.4. Manipulando Pacotes com o dpkg

O dpkg é o comando básico para lidar com pacotes Debian no sistema. Se você tem pacotes .deb, é com o dpkg que você instala ou analisa seu conteúdo. Mas este programa tem apenas uma visão parcial do universo Debian: ele sabe o que está instalado no sistema, e o que for dado na linha de comando, mas não sabe nada dos outros pacotes disponíveis. Assim, ele vai falhar se uma dependência não for satisfeita. Ferramentas como o apt e aptitude, ao contrário, criará uma lista de dependências para instalar tudo o mais automaticamente possível.

5.4.1. Instalando pacotes

dpkg é, principalmente, a ferramenta para instalar um pacote Debian já disponível (já que ele não baixa nada). Para isto, usamos sua opção -i ou --install.

Exemplo 5.2. Instalação de um pacote com dpkg

# dpkg -i man-db_2.8.5-2_amd64.deb
(Lendo banco de dados ... 14913 ficheiros e directórios actualmente instalados.)
A preparar para desempacotar .../man-db_2.8.5-2_amd64.deb ...
A descompactar man-db (2.8.5-2) sobre (2.8.5-2) ...
Configurando man-db (2.8.5-2) ...
Updating database of manual pages ...
man-db.service is a disabled or a static unit not running, not starting it.
A processar 'triggers' para mime-support (3.62) ...
Podemos ver os diferentes passos realizados pelo dpkg; sabemos, portanto, em qual ponto um erro ocorreu. A instalação pode também ser realizada em dois estágios: primeiro desempacotar, depois configurar. O apt usa isto, limitando o número de chamadas para o dpkg (já que cada chamada é custosa, devido à carga do banco de dados em memória, principalmente da lista de arquivos já instalados).

Exemplo 5.3. Desempacotando e configurando separadamente

# dpkg --unpack man-db_2.9.4-2_amd64.deb
(Reading database ... 227466 files and directories currently installed.)
Preparing to unpack man-db_2.9.4-2_amd64.deb ...
Unpacking man-db (2.9.4-2) over (2.9.4-2) ...
Processing triggers for mime-support (3.69) ...
# dpkg --configure man-db
Setting up man-db (2.9.4-2) ...
Updating database of manual pages ...
man-db.service is a disabled or a static unit not running, not starting it.

Algumas vezes, o dpkg vai falhar ao instalar um pacote e retornar um erro; se o usuário ordenar que ele ignore isto, ele vai mostrar apenas um aviso; é por esta razão que temos as diferentes opções --force-*. O comando dpkg --force-help, ou a documentação deste comando, vai dar uma lista completa destas opções. O erro mais frequente, que você vai encontrar, cedo ou tarde, é colisão de arquivos. Quando um pacote contém um arquivo que já está instalado por outro pacote, o dpkg se recusará a instalá-lo. As seguintes mensagens vão aparecer:
Desempacotando libgdm (from .../libgdm_3.8.3-2_amd64.deb) ...
dpkg: erro processando /var/cache/apt/archives/libgdm_3.8.3-2_amd64.deb (--unpack):
 tentando sobrescrever '/usr/bin/gdmflexiserver', que também está no pacote gdm3 3.4.1-9
Neste caso, se você pensa que se você acha que substituir este arquivo não é um risco significante à estabilidade de seu sistema (o que normalmente é o caso), você pode usar a opção --force-overwrite, que diz ao dpkg para ignorar este erro e sobreescrever o arquivo.
Mesmo que existam muitas opções --force-* disponíveis, apenas --force-overwrite costuma ser usada regularmente. Estas opções existem apenas para situações excepcionais, raramente encorajadas no Debian Stable. É melhor evitar usá-las o máximo possível para respeitar as regras impostas pelo mecanismo de empacotamento. Não esqueça, estas regras garantem a consistência e estabilidade de seu sistema.

5.4.2. Remoção de pacote

Invocando o dpkg com a opção -r ou --remove, seguida pelo nome de um pacote, remove o pacote. Esta remoção é, entretanto, incompleta: todos os arquivos de configuração, scripts do mantenedor, arquivos de log (logs de sistema) e outros dados do usuário manipulados pelo pacote permanecem. Dessa forma, a desativação do programa é feita facilmente desinstalando-o, e ainda é possível reinstalá-lo rapidamente com a mesma configuração. Para remover completamente tudo associado a um pacote, use a opção -P ou --purge, seguida do nome do pacote.

Exemplo 5.4. Remoção e expurgo do pacote debian-cd

# dpkg -r debian-cd
(Lendo base de dados ... 228705 arquivos e diretórios já instalados.)
Removendo debian-cd (3.1.35) ...
# dpkg -P debian-cd
(Lendo base de dados ... 228049 arquivos e diretórios já instalados.)
Limpando arquivos de configuração para debian-cd (3.1.35) ...

5.4.3. Consultando o banco de dados do dpkg e inspecionando os arquivos .deb

Antes de concluir esta seção, vamos estudar as opções do dpkg que consultam o banco de dados interno para obter informações. Dando primeiro as opções no formato longo e depois os correspondentes formatos curtos (que, evidentemente, vão ter os mesmo argumentos possiveis) citamos
  • --listfiles pacote (ou -L), que lista os arquivos instalados pelo pacote;
  • --search arquivo (ou -S), que encontra o(s) pacote(s) contendo o arquivo;
  • --status pacote (ou -s), que mostra os cabeçalhos dos pacotes instalados;
  • --list (ou -l), que mostra a lista de pacotes conhecidos do sistema e seus status de instalação;
  • --contents file.deb (ou -c), que lista os arquivos no pacote Debian específico;
  • --info file.deb (ou -I), que mostra os cabeçalhos deste pacote Debian.

Exemplo 5.5. Várias consultas com o 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: 15719
Maintainer: Michael Stone <mstone@debian.org>
Architecture: amd64
Multi-Arch: foreign
Version: 8.30-3
Pre-Depends: libacl1 (>= 2.2.23), libattr1 (>= 1:2.4.44), libc6 (>= 2.28), libselinux1 (>= 2.1.13)
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  baobab               <none>          <node>          (no description available)
un  base                 <none>          <none>          (no description available)
un  base-config          <none>          <none>          (no description available)
ii  base-files           11              amd64           Debian base system miscellaneous files
ii  base-passwd          3.5.46          amd64           Debian base system master password and group files
ii  bash                 5.0-4           amd64           GNU Bourne Again SHell
[..]
$ dpkg -c /var/cache/apt/archives/gnupg-utils_2.2.12-1_amd64.deb
drwxr-xr-x root/root         0 2018-12-15 02:17 ./
drwxr-xr-x root/root         0 2018-12-15 02:17 ./usr/
drwxr-xr-x root/root         0 2018-12-15 02:17 ./usr/bin/
-rwxr-xr-x root/root      3516 2018-12-15 02:17 ./usr/bin/gpg-zip
-rwxr-xr-x root/root    866256 2018-12-15 02:17 ./usr/bin/gpgcompose
-rwxr-xr-x root/root     30792 2018-12-15 02:17 ./usr/bin/gpgparsemail
-rwxr-xr-x root/root     84432 2018-12-15 02:17 ./usr/bin/gpgsplit
-rwxr-xr-x root/root    154952 2018-12-15 02:17 ./usr/bin/gpgtar
-rwxr-xr-x root/root    166568 2018-12-15 02:17 ./usr/bin/kbxutil
-rwxr-xr-x root/root      1081 2017-08-28 12:22 ./usr/bin/lspgpot
-rwxr-xr-x root/root      2194 2018-11-18 23:37 ./usr/bin/migrate-pubring-from-classic-gpg
-rwxr-xr-x root/root    121576 2018-12-15 02:17 ./usr/bin/symcryptrun
-rwxr-xr-x root/root     18424 2018-12-15 02:17 ./usr/bin/watchgnupg
drwxr-xr-x root/root         0 2018-12-15 02:17 ./usr/sbin/
-rwxr-xr-x root/root      3075 2018-12-15 02:17 ./usr/sbin/addgnupghome
-rwxr-xr-x root/root      2217 2018-12-15 02:17 ./usr/sbin/applygnupgdefaults
drwxr-xr-x root/root         0 2018-12-15 02:17 ./usr/share/
drwxr-xr-x root/root         0 2018-12-15 02:17 ./usr/share/doc/
[...]
$ dpkg -I /var/cache/apt/archives/gnupg-utils_2.2.12-1_amd64.deb
 new Debian package, version 2.0.
 size 857408 bytes: control archive=1844 bytes.
    1564 bytes,    32 lines      control              
    1804 bytes,    28 lines      md5sums              
 Package: gnupg-utils
 Source: gnupg2
 Version: 2.2.12-1
 Architecture: amd64
 Maintainer: Debian GnuPG Maintainers <pkg-gnupg-maint@lists.alioth.debian.org>
 Installed-Size: 1845
 Depends: libassuan0 (>= 2.0.1), libbz2-1.0, libc6 (>= 2.25), libgcrypt20 (>= 1.8.0), libgpg-error0 (>= 1.26-2~), libksba8 (>= 1.3.4), libreadline7 (>= 6.0), zlib1g (>= 1:1.1.4)
 Recommends: gpg, gpg-agent, gpgconf, gpgsm
 Breaks: gnupg (<< 2.1.21-4), gnupg-agent (<< 2.1.21-4)
 Replaces: gnupg (<< 2.1.21-4), gnupg-agent (<< 2.1.21-4)
 Section: utils
 Priority: optional
 Multi-Arch: foreign
 Homepage: https://www.gnupg.org/
 Description: GNU privacy guard - utility programs
  GnuPG is GNU's tool for secure communication and data storage.
  .
  This package contains several useful utilities for manipulating
  OpenPGP data and other related cryptographic elements.  It includes:
  .
   * addgnupghome -- create .gnupg home directories
   * applygnupgdefaults -- run gpgconf --apply-defaults for all users
   * gpgcompose -- an experimental tool for constructing arbitrary
                   sequences of OpenPGP packets (e.g. for testing)
   * gpgparsemail -- parse an e-mail message into annotated format
   * gpgsplit -- split a sequence of OpenPGP packets into files
   * gpgtar -- encrypt or sign files in an archive
   * kbxutil -- list, export, import Keybox data
   * lspgpot -- convert PGP ownertrust values to GnuPG
   * migrate-pubring-from-classic-gpg -- use only "modern" formats
   * symcryptrun -- use simple symmetric encryption tool in GnuPG framework
   * watchgnupg -- watch socket-based logs
[..]

5.4.4. Arquivo de log do dpkg

dpkg mantém um log de todas as suas ações em /var/log/dpkg.log. Este log é extremamente detalhado, pois detalha todos os passos da manipulação de pacotes pelo dpkg. Adicionalmente oferece uma forma de rastrear o comportamento do dpkg, ele ajuda, sobretudo, a manter um histórico do desenvolvimento do sistema: pode-se encontrar o exato momento em que cada pacote foi instalado ou atualizado, e esta informação pode ser extremamente útil para entender uma mudança de comportamento recente. Adicionalmente, com todas as versões sendo registradas, é fácil cruzar os dados com a informação em changelog.Debian.gz para o pacote em questão, ou mesmo com o relatório de defeitos on line (bug reports online).

5.4.5. Suporte Multi-Arqu

Todos os pacotes Debian tem um campo Arquitetura na informação de controle dele. Este campo pode conter também “Todos” (para aqueles pacotes que são de todas as arquiteturas independentemente) ou o nome da arquitetura que ele aponta (como “amd64”, “armhf”, …). Neste último caso, por padrão, dpkg apenas aceitará instalar o pacote, se a sua arquitetura combinar com a arquitetura do host como retornado pelo dpkg --print-arquitetura.
Esta restrição garante que os usuários não acabam com os binários compilados para uma arquitetura incorreta. Tudo seria perfeito, exceto que (alguns) computadores podem executar binários para várias arquiteturas, quer nativamente (um sistema de "amd64" pode rodar binários "i386") ou através de emuladores.

5.4.5.1. Habilitando Multi-Arqu

O suporte multi-arquitetura do dpkg permite aos usuários definir arquiteturas “estrangeiras” que podem ser instaladas no sistema atual. Isto é simplesmente feito com dpkg --add-architecture como no exemplo abaixo. Há um correspondente dpkg --remove-architecture para remover o suporte de uma arquitetura externa, mas ele só pode ser usado quando nenhum pacote desta arquitetura permanece.
# dpkg --print-architecture
amd64
# dpkg --print-foreign-architectures
# dpkg -i gcc-9-base_9.3.0-22_armhf.deb
dpkg: error processing archive gcc-9-base_9.3.0-22_armhf.deb (--install):
 package architecture (armhf) does not match system (amd64)
Errors were encountered while processing:
 gcc-9-base_9.3.0-22_armhf.deb
# dpkg --add-architecture armhf
# dpkg --add-architecture armel
# dpkg --print-foreign-architectures
armhf
armel
# dpkg -i gcc-9-base_9.3.0-22_armhf.deb
(Reading database ... 456367 files and directories currently installed.)
Preparing to unpack gcc-9-base_9.3.0-22_armhf.deb ...
Unpacking gcc-9-base:armhf (9.3.0-22) ...
Setting up gcc-9-base:armhf (9.3.0-22) ...
# 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. Alterações relativas ao Multi-Arqu

Para fazer Multi-Arqu realmente útil e utilizável, as bibliotecas tiveram de ser reempacotadas e movidas para um diretório de uma arquitetura específica, de modo que várias cópias (apontando para diferentes arquiteturas) pudessem ser instaladas lado a lado. Tais pacotes atualizados contém o campo de cabeçalho “Multi-Arqu: same” para dizer ao sistema de empacotamento que as várias arquiteturas do pacote podem ser seguramente co-instaladas (e que os pacotes só podem satisfazer as dependências de pacotes da mesma arquitetura). As bibliotecas mais importantes foram convertidas desde a introdução do multi-arch no Debian 7 Wheezy, mas existem muitas bibliotecas que provavelmente nunca serão convertidas a menos que alguém peça especificamente por elas (através de um bugreport, por exemplo).
$ dpkg -s gcc-9-base
dpkg-query: error: --status needs a valid package name but 'gcc-9-base' is not: ambiguous package name 'gcc-9-base' with more than one installed instance

Use --help for help about querying packages.
$ dpkg -s gcc-9-base:amd64 gcc-9-base:armhf | grep ^Multi
Multi-Arch: same
Multi-Arch: same
$ dpkg -L libgcc-s1:amd64 |grep .so
/lib/x86_64-linux-gnu/libgcc_s.so.1
$ dpkg -S /usr/share/doc/gcc-9-base/copyright
gcc-9-base:amd64, gcc-9-base:armhf: /usr/share/doc/gcc-9-base/copyright
Vale a pena notar que o pacote Multi-Arqu: same devem ter seus nomes qualificados com sua arquitetura para ser inequivocamente identificável. Eles também têm a possibilidade de compartilhar arquivos com outras instâncias do mesmo pacote; dpkg garante que todos os pacotes têm arquivos bit-por-bit idênticos quando eles são compartilhados. Por último, mas não menos importante, todas as instâncias de um pacote devem ter a mesma versão. Devem, portanto, ser atualizados em conjunto.
Suporte Multi-Arch também traz alguns desafios interessantes na forma como são tratadas as dependências. Satisfazer uma dependência requer um pacote marcado “Multi-Arqu: foreign” ou um pacote cuja arquitetura corresponde ao do pacote declarando a dependência (no processo de resolução de dependência, pacotes independentes de arquitetura são assumidos ser da mesma arquitetura que o host). A dependência também pode ser enfraquecida para permitir que qualquer arquitetura de cumpri-la, com a sintaxe pacote:any, mas pacotes estrangeiros só podem satisfazer uma tal dependência, se eles são marcados “Multi-Arch: allowed”.