Como obter uma lista de pacotes recém-instalados após o tempo x sem pacotes removidos após o tempo x?

3

A partir de /var/log/apt/history.log , é possível recuperar uma lista de pacotes instalados e removidos no tempo x com base em registros de data e hora, mas editar o arquivo é bastante irritante, então estou procurando um (conjunto de) comando (s) ) para obter a lista efetiva de pacotes que foram instalados após timestamp x_0 (= pacotes que foram instalados após timestamp x_0 minus pacotes que foram removidos após timestamp x_0 ) na forma de uma lista de nomes de pacotes.

software-center exibe apenas as alterações cronologicamente e synaptic não possui uma coluna que represente o tempo de instalação. dpkg-query parece promissor, mas agradeço a ajuda de alguém que possa descobrir isso em minutos, em vez de dias (o último se aplica a mim mesmo).

Estou executando o Ubuntu 14.10.

    
por Karl Richter 30.12.2014 / 11:51

2 respostas

1

Parece que dpkg não mostra explicitamente nenhuma informação sobre as datas de instalação dos pacotes.

Então, para uma única execução, eu usaria algo como o seguinte one-liner:

cat /var/log/apt/history.log |perl -lne 'next unless /^Start-Date: ([^ ]+)/ && $1 ge "2015-04-26" .. 1; next unless /^(Install|Purge|Remove): (.*)$/; $c = $1; $s = $2; $s =~ s/\([^\)]*\)//g; @packages = map { /^(.*?):/ ? $1 : $_} split /\s*,\s*/, $s; if ($c=~/^Install$/){ $h{$_} = 1 for @packages;} if ($c=~/^(Purge|Remove)$/) {delete $h{$_} for @packages;} END{print for sort keys %h;}'

A data de início (x_0) foi codificada no comando ( "2015-04-26" ).

Por vezes, a utilização mais adequada seria um script autónomo, como este installed_packages.pl :

#!/usr/bin/perl

# use as follows:
# ./installed_packages.pl '2015-04-26' /var/log/apt/history.log
# or
# ./installed_packages.pl '2015-04-26 16:08:36' /var/log/apt/history.log

use strict;
use warnings;

# the script expects start date as first argument
my $START_DATE = shift @ARGV;

# hash (dict) to accumulate installed & not removed packages 
my %installed;
# flag to mark the beginning of "interesting" period of time
my $start = 0;

# loop over lines from the input file
while (my $line = <>){
    # remove end-of-line character 
    chomp $line;

    # skip everything until date becomes greater (or equal) than our x_0
    $start ||= $line =~ /^Start-Date: ([^ ]+)/ && $1 ge $START_DATE;
    next unless $start;

    # we're only interested in lines like 
    # Install: tupi-data:amd64 (0.2+git02-3build1, automatic), tupi:amd64 (0.2+git02-3build1), libquazip0:amd64 (0.6.2-0ubuntu1, automatic)
    # or
    # Remove: aptitude-common:amd64 (0.6.8.2-1ubuntu4)
    # + separate action (install/remove/purge) from package list
    next unless $line =~ /^(Install|Purge|Remove): (.*)$/; 
    my ($action, $packages_str) = ($1, $2);

    # remove versions from the list (they're in parentheses)
    $packages_str =~ s/\(.*?\)//g;

    # split single line into array of package names
    my @packages = split /\s*,\s*/, $packages_str;
    # remove architecture name (comes after ':')
    s/:.*// for @packages;

    # if packages have been installed, add them all to the hash (dict) of installed packages
    if ($action =~ /^Install$/ ){
        $installed{$_} = 1 for @packages;
    }

    # if packages have been removed, remove them all from the hash (dict) of installed packages
    if ($action =~ /^(Purge|Remove)$/) {
        delete $installed{$_} for @packages;
    }
}

# print all installed and not removed packages, in alphabetical order
for my $p ( sort keys %installed ){
    print "$p\n";
}

Uso:

./installed_packages.pl '2015-04-26' /var/log/apt/history.log

ou

perl ./installed_packages.pl '2015-04-26' /var/log/apt/history.log

Para uso interativo frequente eu adicionaria a validação de argumentos de script (formato de data de início), implemente a opção -h para exibir ajuda curta e possivelmente converta a data de início para a opção nomeada ( --start ).

Boa sorte!

    
por Hln 29.04.2015 / 10:19
0

Eu peguei o código-fonte de esta resposta e aumentei um pouco.

O valor agregado é que você também obtém pacotes removidos e removidos e a saída pode ser filtrada com grep .

Listar pacotes instalados:

./installed_packages.pl '2015-04-28' /var/log/apt/history.log | grep Installed:

ou isso para removido ou removido:

./installed_packages.pl '2015-04-28' /var/log/apt/history.log | grep -Ei '(Purged|Removed)'

Código-fonte:

#!/usr/bin/perl

# use as follows:
# ./installed_packages.pl '2015-04-26' /var/log/apt/history.log
# or
# ./installed_packages.pl '2015-04-26 16:08:36' /var/log/apt/history.log

use strict;
use warnings;

# the script expects start date as first argument
my $START_DATE = shift @ARGV;

# hash (dict) to accumulate installed & not removed packages 
my %installed;
my %removed;
my %purged;
# flag to mark the beginning of "interesting" period of time
my $start = 0;

# loop over lines from the input file
while (my $line = <>){
    # remove end-of-line character 
    chomp $line;

    # skip everything until date becomes greater (or equal) than our x_0
    $start ||= $line =~ /^Start-Date: ([^ ]+)/ && $1 ge $START_DATE;
    next unless $start;

    # we're only interested in lines like 
    # Install: tupi-data:amd64 (0.2+git02-3build1, automatic), tupi:amd64 (0.2+git02-3build1), libquazip0:amd64 (0.6.2-0ubuntu1, automatic)
    # or
    # Remove: aptitude-common:amd64 (0.6.8.2-1ubuntu4)
    # + separate action (install/remove/purge) from package list
    next unless $line =~ /^(Install|Purge|Remove): (.*)$/; 
    my ($action, $packages_str) = ($1, $2);

    # remove versions from the list (they're in parentheses)
    # $packages_str =~ s/\(.*?\)//g;

    # split single line into array of package names
    my @packages = split /\s*,\s*/, $packages_str;
    # remove architecture name (comes after ':')
    s/:.*// for @packages;

    # if packages have been installed, add them all to the hash (dict) of installed packages
    if ($action =~ /^Install$/ ){
        $installed{$_} = 1 for @packages;
    }

    # if packages have been removed, add them all to the hash (dict) of installed packages
    if ($action =~ /^Remove$/) {
        $removed{$_} = 1 for @packages;
    }

    # if packages have been purged, add them all to the hash (dict) of installed packages
    if ($action =~ /^Purge$/) {
        $purged{$_} = 1 for @packages;
    }
}

# print all installed and not removed packages, in alphabetical order
for my $p ( sort keys %installed ){
    print "Installed: $p\n";
}

for my $p ( sort keys %removed ){
    print "Removed: $p\n";
}

for my $p ( sort keys %removed ){
    print "Purged: $p\n";
}
    
por A.B. 29.04.2015 / 11:04