Query dpkg para todos os pacotes instalados / removidos da imagem padrão

1

Existe alguma maneira de consultar dpkg para informar quais pacotes foram adicionados / removidos desde a instalação básica de um sistema?

Estou usando o Debian 5.

    
por AJ. 27.04.2011 / 02:42

1 resposta

4

Tanto quanto eu posso dizer, não há uma maneira direta de fazer isso. O banco de dados dpkg contém apenas o estado atual dos pacotes, portanto, qualquer histórico teria que ser deduzido ou analisado dos logs.

Resposta curta (também conhecida como one-liner para o preguiçoso)

dpkg-query -f='${Package}\n' -W  | grep -vx "'grep 'Setting up' /var/log/installer/syslog | cut -d' ' -f8'"

Explicação

1. Obtendo uma lista de pacotes instalados pelo instalador

debian-installer escreve seus registros em /var/log/installer . Há um arquivo syslog lá e nós podemos grep para ver quais pacotes foram instalados:

grep 'Setting up' /var/log/installer/syslog

Note que estamos procurando Configurando ou Desembalando em vez de por exemplo. Selecionando já que queremos todos os pacotes, incluindo aqueles instalados como dependências. Precisamos extrair nomes de pacotes a partir disso:

grep 'Setting up' /var/log/installer/syslog | cut -d' ' -f8

2. Obtendo uma lista de pacotes atualmente instalados

Agora precisamos de uma lista de pacotes atualmente instalados para fazer um reverse grep contra. Queremos apenas nomes de pacotes, por exemplo. sem descrições para evitar a filtragem muito clara, então dpkg -l não é ótimo. Podemos usar dpkg-query em vez disso:

dpkg-query -f='${Package}\n' -W

3. Filtrando pacotes instalados na inicialização

Tudo o que resta fazer é filtrar o conteúdo da primeira lista da segunda lista. Para isso usamos grep -vx . -v é para "reverso", -x (ou --line-regex ) é para "exato". Este último corresponde apenas a linhas inteiras, o que garante que filtramos, por exemplo. apt mas não aptitude .

Então aqui está a coisa toda montada:

 # currently installed
 current="'dpkg-query -f='${Package}\n' -W'"
 # base install (let's also remove duplicates to make verification easier)
 base="'grep 'Setting up' /var/log/installer/syslog | cut -d' ' -f8 | sort | uniq'"
 # your answer
 extra="'echo "$current" | grep -vx "$base"'"
 removed="'echo "$base" | grep -vx "$current"'"

4. Verificando resultados

Para verificar se conseguimos os pacotes certos, podemos contar as linhas:

 echo "$base" | wc -l         # 160
 echo "$current" | wc -l      # 1677
 echo "$extra" | wc -l        # 1517
 echo "$removed" | wc -l      # 0 (I used "netinst")

Atualização: se /var/log/installer não estiver lá

/var/log/installer é removido do sistema se o pacote installation-report for removido. Nesse caso, podemos tentar obter a lista de pacotes que foram carregados pelo instalador do arquivo /var/log/dpkg.log.* mais antigo.

Existem 2 problemas com isso:

  1. não há garantia de que as informações de que precisamos ainda estão lá desde que esses arquivos foram girados (ainda no meu caso - instalar em 2010-10-01 e muitas atualizações desde então).
  2. o arquivo mais antigo provavelmente incluirá logs de pacotes sendo instalados após a instalação inicial.

Não há nada que possamos fazer (1). Com (2) podemos manualmente (por timestamps talvez) estabelecer qual pacote conclui a instalação por debian-installer . No meu caso, parece ter sido os-prober (o que acredito ser comum em alguns casos devido a sua relação com grub ).

Veja o código de exemplo para obter $base usando este método:

 last_installed="os-prober"
 base_dpkglog="'zgrep ' install ' dpkg.log.8.gz | cut -d' ' -f4 | while read pkg; do 
     [ "$pkg" != "$last_installed" ] && echo $pkg || { echo $pkg; break; }
 done | sort | uniq'"

E uma verificação rápida:

 echo "$base_dpkglog" | wc -l                    # 159
 echo "$base" | wc -l                            # 160
 diff -d <(echo "$base") <(echo "$base_dpkglog") # 31d30
                                                 # < dpkg
    
por 01.05.2011 / 12:06