14

Software Center somehow shows quite short list of installed packages. How to get it in text file?

I tried:

> dpkg --get-selections|wc -l
3265

> aptitude search '~i!~M'|wc -l
1181

> dpkg -l | grep ^ii | sed 's_  _\t_g' | cut -f 2|wc -l
3076

> dpkg --get-selections | grep -v deinstall|wc -l
3076

> apt-mark showmanual|wc -l
1181

I know that I've installed few dozens packages, not thousands. I need in the list exactly packages I'd choosen without dependencies to review it.

UPDATE

Many thanks to @kos, I got finally the list with that command:

> zcat /var/log/apt/history.log.*.gz | cat - /var/log/apt/history.log | grep -Po '^Commandline: apt-get install \K.*' | tr ' ' '\n' | grep -v '\-\-reinstall'|grep -v '\-\-force-yes'|grep -v '\-y'|grep -v '\-f'|sort|uniq wc -l
103
zuba
  • 2,393

6 Answers6

13

This doesn't answer the question exactly: it rather gives a command to list all the apt-get install commands ever run along with some advices on how to parse the list further in order to get a list of all the apt-get install command ever run excluding those run by Ubiquity, since the perfect solution for this task seems to not exist.

zcat /var/log/apt/history.log.*.gz | cat - /var/log/apt/history.log | grep -Po '^Commandline:(?= apt-get)(?=.* install ) \K.*'
  • zcat /var/log/apt/history.log.*.gz: decompresses all the compressed apt logs in /var/log/apt, concatenates them and prints to stdout;
  • cat - /var/log/apt/history.log: appends /var/log/apt/history.log and prints to stdout;
  • grep -Po '^Commandline:(?= apt-get)(?=.* install ) \K.*': selects only the lines starting with Commandline: apt-get containing install with a leading and trailing space and prints the remainder of each selected line to stdout;

This will output the list of all the apt-get install commands ever run (the only undesidered output could be an apt-get-non-install command mentioning an install package, but that package doesn't exist (yet?), at least in the default repositories);

Note: In my installation (Ubuntu 15.04 64-bit), the first four commands listed are those run by Ubiquity during the installation; to exclude these, you may pipe the output to sed:

sed '1,4d'

So that the final approximate command for Ubuntu 15.04 64-bit would be:

zcat /var/log/apt/history.log.*.gz | cat - /var/log/apt/history.log | grep -Po '^Commandline:(?= apt-get)(?=.* install ) \K.*' | sed '1,4d'
A.B.
  • 90,397
kos
  • 35,891
  • 2
    This doesn't include any apt install commands. This will: zcat /var/log/apt/history.log.*.gz | cat - /var/log/apt/history.log | grep -Po '^Commandline:(?= apt(-get)?)(?=.* install ) \K.*' | sed '1,4d' – mbomb007 Mar 01 '21 at 16:41
  • Note that on Debian by default only one year of apt history is kept, so this will not return results beyond that. – Chad Schouggins May 09 '22 at 01:59
12
apt-mark showmanual

will give you a list of all manually installed packages without the dependencies - the important thing to take note of is that it will also show what package were installed during Ubuntu setup.

To write the output to a file:

apt-mark showmanual > somefile

There are actually many other ways, such as using this command

comm -23 <(apt-mark showmanual | sort -u) <(gzip -dc /var/log/installer/initial-status.gz | sed -n 's/^Package: //p' | sort -u) 

Although I have absolutely no idea how the above works ;)

To view packages installed by date:

Packages installed by date use cat /var/log/dpkg.log | grep "\ install\ > somefile"
Packages installed using dpkg use ls -l /var/log/dpkg* > somefile - this one is probably what you're looking for.

To view packages installed using dpkg:

This file contains the above information: /var/log/dpkg.log

TellMeWhy
  • 17,484
  • I doubt I've choosen 1181 packages, really.
    > apt-mark showmanual|wc -l
    1181
    
    – zuba Oct 01 '15 at 10:59
  • @zuba The reason is that all the packages that were installed during Ubuntu setup are also marked manual. – Nephente Oct 01 '15 at 11:04
  • I get it. How can I select the packages I'd choosen manually after installation. Can I e.g. select packages with installation dates, to filter out those with dates after installation date? – zuba Oct 01 '15 at 11:06
  • @zuba I've now added how to view packages installed by date – TellMeWhy Oct 01 '15 at 11:19
  • @DevRobot. Could you provide a link to where you found that command? It's really nifty. I had no idea, about the initial-status.gz :-) – Nephente Oct 01 '15 at 11:19
  • @nephente http://superuser.com/a/777603 – TellMeWhy Oct 01 '15 at 11:23
2

Here's a slight improvement to the accepted answer that lists the commands with the dates that they were issued on in chronological order. I find the chronological component very helpful if you want to know what you changed when on your system.

The original answer also took only "apt-get install" commands, but apt recently supported direct "apt install" commands which were not captured by the answer. I made the PCRE a bit more lenient to include all apt commands as well.

zcat /var/log/apt/history.log.*.gz | \
cat - /var/log/apt/history.log | \
grep -Po '^Commandline:(?= apt)(?=.* install ) \K.*|^Start-Date: \K.*' | \
grep -B1 "^apt" | \
grep -v -- "^--" | \
paste -d " "  - - | \
sort
Eliah Kagan
  • 117,780
DevDoc
  • 21
  • 1
2

This command will give a list of manually installed packages, as well as those where their "automatically installed" reverse dependencies has been removed (for instance, if you remove the ubuntu-server metapackage, its dependencies will no longer be marked automatic, and will now be on this list):

apt list --installed | grep -v automatic

In other words, the above list will return all packages with either no reverse dependencies, or where they are also marked as manually installed.

Artur Meinild
  • 26,018
2

This is actually more complicated than it seems, and there are quite a few similar questions on Ask Ubuntu.

I've found that looking in /var/log/apt/history.log and the older gzipped versions of that log, any thing installed by an apt-get install command is listed as installed by that command.

So:

grep "apt-get install" /var/log/apt/history.log

Will show you all of them for the period that the current apt history log covers. You'll need to gunzip your older logs, and grep those to get all of your information together. The grep commands could all be redirected into a text file to give you a nice list.

This is probably only useful for your case if Software Center uses apt-get install when installing. I know that Software Center is a front end for apt but not sure it uses that command explicitly.

Arronical
  • 19,893
1

Here is a Ruby script that uses rdepends to check if a package is a dependency for another installed package. That will not tell exactly what you selected, but that does not depend on your log files (which might have been rotated).

Installing packages listed as root packages will install all the packages listed in children packages. So you should end up with almost (see drawbacks below) the same packages list.

The children list will shows the packages that are dependencies of other children packages or root packages.

There are some drawbacks with this approach:

  • Some packages might not be listed as root when they are dependencies of some optional, recommended package you selected. For example, on my server apache2 is listed in children packages because I also have libapache2-mod-php, libapache2-mpm-itk and python-letsencrypt-apache installed which have apache2 as a dependency.
  • Cyclic dependencies (packages that directly or indirectly depends on each others) will be listed in Children packages (for example: libapache2-mod-php and libapache2-mod-php7.0). There is a section listing the probable cycle (check the package ancestries for 5 generations), you should include it to have the same list of packages (unless I've overlooked something else).
#!/usr/bin/env ruby

class ListRootPackages def run count = manual_marked_packages.count @dependencies ||= {}

@root_packages ||= begin
  manual_marked_packages.each_with_index.map do |package, index|
    STDERR.print &quot;   #{index + 1} / #{count} \r&quot;

    intersection = manual_marked_packages &amp; reverse_dependencies(package)

    if intersection.any?
      @dependencies[package] = intersection
      nil
    else
      package
    end
  end.compact
end

end

def potential_cyclic_dependences run

@potential_cyclic_dependences ||= @dependencies.keys.map do |package|
  package unless has_root_ancestor?(package, 5)
end.compact

end

def has_root_ancestor?(package, level=0) return true if @root_packages.include?(package) return false if level.zero?

@dependencies[package].any? { |parent| has_root_ancestor?(parent, level - 1) }

end

def root_packages run @root_packages end

def dependencies run @dependencies end

def manual_marked_packages @manual_marked_packages ||= parse_cli_list(apt-mark showmanual) end

private

def reverse_dependencies(package) parse_cli_list(apt-cache rdepends #{package})[2..-1] end

def parse_cli_list(list) list.split("\n").map(&:strip) end end

list = ListRootPackages.new list.run

puts "===== Root Packages (#{list.root_packages.count}) =====" puts list.root_packages.join("\n") puts

puts "===== Children packages (#{list.dependencies.count}) =====" puts list.dependencies.map { |package, parents| "#{package}: #{parents.join(', ')}" }.join("\n") puts

puts "===== Potential cyclic dependencies (#{list.potential_cyclic_dependences.count}) =====" puts list.potential_cyclic_dependences.join(", ")

if somebody wants to convert that to Bash or Python, that would be nice since Ruby is less commonly installed on servers than Bash or Python.

Zanna
  • 70,465
ybart
  • 111