// Datei: ./werkzeuge/paketoperationen/liste-der-installierten-pakete-anzeigen-und-deuten.adoc

// Baustelle: Fertig

[[liste-der-installierten-pakete-anzeigen-und-deuten]]

=== Liste der installierten Pakete anzeigen und deuten ===

// Stichworte für den Index
(((Paket, installiertes anzeigen)))
(((Paketliste, vollständig ausgeben)))
Diese Aktion betrifft häufig nicht nur ein einzelnes Paket, sondern den
Gesamtbestand an Software, die auf Ihrem Linuxsystem installiert sind
oder waren. Im Alltag ergeben sich eine ganze Reihe von
Anwendungsfällen, bei denen diese Aktion durchgeführt wird.

Hintergrund für den _Fall 1_ ist der Wunsch nach einem Überblick zum
Gesamtzustand eines Systems und vor allem der Software, die darauf
installiert ist. Das betrifft insbesondere die Rechnersysteme, die Sie
nicht selbst eingerichtet haben und deren Betreuung Ihnen obliegt, bspw.
Geräte im Auslieferungszustand oder im Rahmen der Wartung als
Bestandteil eines Kundenauftrags. Dabei kommt häufig die
Berücksichtigung ``gewachsener Infrastruktur'' ins Spiel.

_Fall 2_ betrifft ``großflächige'' Änderungen auf einem Rechnersystem.
Sie überprüfen, ob diese korrekt abgelaufen sind. _Fall 3_ betrifft die
Entwicklung, hier ist die Fehlersuche bei den Paketwerkzeugen zu nennen.

Zu den konkreten Aktionen zählt weiterhin das Herausfinden, ob ein
bestimmtes Paket oder Programm auf Ihrem Rechnersystem überhaupt
installiert ist, und falls ja, ob dieses vollständig installiert und
(bereits) konfiguriert wurde. Wurde es hingegen entfernt, ist zu klären,
ob es vollständig entfernt wurde oder noch ``Reste'' übrig sind, bspw.
paketspezifische Konfigurationsdateien.

Für die Kommandozeile existieren mittlerweile drei grundlegende 
Möglichkeiten. Einerseits ist das `dpkg -l`, andererseits 
`aptitude search '~i'` und drittens `apt list --installed`. Die 
Darstellung in den graphischen Programme klären wir weiter unten genauer.

==== `dpkg -l` 'Paketname' (Langform `--list`) ====

// Stichworte für den Index
(((dpkg, -l)))
(((dpkg, --list)))
(((dpkg-query, -l)))
(((dpkg-query, --list)))
`dpkg` wird für diese Aufgabe sehr häufig genutzt. Intern leitet `dpkg` den
Aufruf an das Abfragewerkzeug `dpkg-query` weiter.

Ohne die Angabe des Paketnamens zeigen Sie alle Pakete und Paketreste an, die 
auf Ihrem System derzeit installiert sind. Geben Sie ein oder mehrere Pakete 
als Parameter durch Leerzeichen getrennt an, erhalten Sie nur Informationen
zu diesen benannten Paketen. In nachfolgender Paketliste zeigen die einzelnen 
Spalten nacheinander den Paketzustand, den Namen des Pakets (siehe 
<<benennung-eines-debian-pakets>>), dessen Version und die dazugehörige
Kurzbeschreibung dazu.

.Vollständige Paketliste mit `dpkg`
----
$ dpkg -l
Gewünscht=Unbekannt/Installieren/R=Entfernen/P=Vollständig Löschen/Halten
| Status=Nicht/Installiert/Config/U=Entpackt/halb konFiguriert/
         Halb installiert/Trigger erWartet/Trigger anhängig
|/ Fehler?=(kein)/R=Neuinstallation notwendig (Status, Fehler: GROSS=schlecht)
||/ Name                                      Version                              Beschreibung
+++-=========================================-====================================-==========================
====================================================
ii  a2ps                                      1:4.14-1.1                           GNU a2ps - 'Anything to Po
stScript' converter and pretty-printer
rc  bsh                                       2.0b4-12                             Java scripting environment
 (BeanShell) Version 2
...
un  xfce4-icon-theme                          <keine>                              (keine Beschreibung vorhanden)
$
----

// Stichworte für den Index
(((Paket, Status anzeigen)))
(((Paket, Zustand anzeigen)))
(((Paketliste, verstehen)))
(((Paketstatus)))
(((Paketzustand)))
Die ersten drei Spalten jeder ausgegebenen Zeile interpretieren Sie
anhand der <<tab.paketzustand>>. Die Begriffe in Klammern nennen die
englischen Übersetzungen – i.d.R. ist das die Langform der jeweiligen
Option. Mit Ausnahme von `W` für 'aWaited trigger' entspricht dabei
der verwendete Buchstabe in der Spalte jeweils dem Anfangsbuchstaben der
Langform der Option.

.Paketzustand deuten
[frame="topbot",options="header",id="tab.paketzustand"]
|====
| gewünschte Aktion durch den Paketmanager | Paketstatus | Fehler-Schalter
| `u`: Unbekannt ('unknown') | `n`: Paket ist nicht installiert ('not
installed') | (leer): kein Fehler
| `i`: Installieren ('installed') | `c`: nur die Konfigurationsdatei ist
vorhanden ('configured') | `R`: eine Neuinstallation ist notwendig ('reinstall')
| `h`: Halten ('hold') | `H`: Paket ist nur halb installiert ('half
installed') |
| `r`: Entfernen ('remove') | `U`: Paket wurde entpackt ('unpacked') |
| `p`: Vollständig Löschen ('purge') | `F`: Fehlgeschlagene
Konfiguration ('failed') |
| | `W`: Trigger erwartet ('aWaited trigger') |
| | `t`: Trigger anhängig ('trigger') |
| | `i`: Installiert ('installed') |
|====

//* gewünschte Aktion durch den Paketmanager:
//** `u`: Unbekannt ('unknown')
//** `i`: Installieren ('installed')
//** `h`: Halten ('hold')
//** `r`: Entfernen ('remove')
//** `p`: Vollständig Löschen ('purge')

//* Paketstatus
//** `n`: Paket ist nicht installiert ('not installed')
//** `c`: nur die Konfigurationsdatei ist vorhanden ('configured')
//** `H`: Paket ist nur halb installiert ('half installed')
//** `U`: Paket wurde entpackt ('unpacked')
//** `F`: Fehlgeschlagene Konfiguration ('failed')
//** `W`: Trigger erwartet ('aWaited trigger')
//** `t`: Trigger anhängig ('trigger')
//** `i`: Installiert ('installed')

//* Fehler-Schalter
//** (leer): kein Fehler
//** `R`: eine Neuinstallation ist notwendig ('reinstall')

Kleinbuchstaben zeigen dabei an, dass alles im grünen Bereich ist.
Großbuchstaben heben hingegen Fehlerfälle oder auch Zustände hervor, die
ihrerseits eine genauere Begutachtung und eine Aktion zu diesem Paket
erfordern. Obige Darstellung mit Buchstaben verwendet sowohl `dpkg`, als
auch `aptitude`. <<tab.paketzustandskombinationen>> zeigt Ihnen die
Status-Kombinationen, die Ihnen häufig im Alltag begegnen werden.

.Alltägliche Kombinationen zum Paketzustand
[frame="topbot",options="header",cols="2,5",id="tab.paketzustandskombinationen"]
|====
| Paketstatus | Beschreibung 
| `ii` | das Paket ist vollständig und fehlerfrei installiert sowie
konfiguriert.
| `rc` | das Paket wurde gelöscht, aber die Konfigurationsdateien sind
noch gespeichert (Abkürzung für 'removed, configured, no error').
| `un` | unbekanntes, nicht installiertes Paket (Abkürzung für 'unknown,
not installed').
| `hi` | das Paket ist installiert, aber auf 'hold' gesetzt. Bei
Softwareaktualisierungen wird das Paket nicht berücksichtigt und in
seinem derzeitigen Zustand belassen (siehe Paketflags in
<<lokale-paketmarkierungen>>).
|====

// Stichworte für den Index
(((dpkg-query, -f)))
(((dpkg-query, --show)))
(((dpkg-query, --showformat)))
(((dpkg-query, -W)))
(((Paketliste, nur die Paketnamen ausgeben)))
Geht es Ihnen lediglich um die Namen der derzeit vollständig installierten Pakete 
ohne deren Versionsnummer und Beschreibung, haben Sie drei Möglichkeiten zur 
Lösung -- a) `dpkg-query` mit einem speziellen Formatstring für die Ausgabe in 
Kombination mit `egrep`, `awk` und `sort`, b) die Kombination aus `dpkg`, `egrep`, 
`awk` und `sort` sowie c) die Verwendung von `dpkg-awk`. `dpkg` selbst bietet von 
sich aus bislang keinen entsprechenden, einzelnen Schalter an, der diese 
spezifische Ausgabe ermöglicht.

Für den *Fall a)* nutzen Sie den Schalter `-W` (Langform `--show`) und den 
Formatstring `-f='${db:Status-Abbrev} ${binary:Package}\n'`. Dabei kürzt `-f` 
die Langform `--showformat` ab. Die Angabe `'${db:Status-Abbrev}'` liefert 
Ihnen den Installationsstatus des Pakets und `$'{binary:Package}\n'` den 
Paketnamen aus der Paketbeschreibung samt Zeilenumbruch am Ende der Zeile. 
Der vollständige Aufruf ist dann wie folgt:

.Nur die Paketnamen ausgeben (`dpkg-query`)
----
$ dpkg-query -W -f='${db:Status-Abbrev} ${binary:Package}\n' * | egrep "^ii" | awk '{ print $2 }' | sort
aapt
acl
acpi
adduser
adwaita-icon-theme
...
$
----

*Fall b)* ist kürzer und kombiniert die Werkzeuge `dpkg`, `egrep`, `awk` und 
`sort` miteinander:
 
.Nur die Paketnamen ausgeben (`dpkg`, `egrep`, `awk` und `sort` kombiniert)
----
$ dpkg -l | egrep "^ii" | awk ' {print $2} ' | sort
aapt
acl
acpi
adduser
adwaita-icon-theme
...
$
----

// Stichworte für den Index
(((Debianpaket, dpkg-awk)))
(((dpkg-awk)))
(((dpkg, /var/lib/dpkg/available)))
(((dpkg, /var/lib/dpkg/status)))
Der dritte *Fall c)* benutzt das Werkzeug `dpkg-awk` aus dem gleichnamigen Paket
<<Debian-Paket-dpkg-awk>>. Das Paket gehört nicht zur Standardinstallation und 
ist daher von ihnen vor der Benutzung nachzuinstallieren. `dpkg-awk` wertet die 
beiden Dateien `/var/lib/dpkg/status` und `/var/lib/dpkg/available` aus.

Mit dem nachfolgenden Aufruf erhalten Sie eine Liste aller Pakete, die
auf ihrem System gerade installiert sind. `dpkg-awk` filtert alle Zeilen
heraus, auf die der regulräre Ausdruck `Status: .* installed$` passt. Mit der 
Angabe `Package` weisen Sie `dpkg-awk` an, nur in die Felder mit den Paketnamen 
zu durchsuchen.

.Die Liste der installierten Pakete mit `dpkg-awk` ermitteln
----
$ dpkg-awk "Status: .* installed$" -- Package
Package: libasan0

Package: libvorbisfile3

Package: libquadmath0

Package: libxkbfile1

...
$
----

Obige Ausgabe bearbeiten Sie mit UNIX/Linux-Tools weiter, bspw. mit `cut` oder 
`sort`, um die Ausgabe ihren Wünschen anzupassen.


==== `aptitude search '~i'` ====

// Stichworte für den Index
(((aptitude, search ~i)))
(((aptitude, search ?installed)))
`aptitude` kennt dazu das Unterkommando `search` und erwartet danach
entweder einen Paketnamen oder ein Flag. In diesem Fall ist es das Flag
`~i` für ``installierte Pakete'' (Langform `?installed`).

Wie bereits oben genannt, verwendet `aptitude` in der Ausgabe die
gleichen Buchstaben wie `dpkg` (siehe <<tab.paketzustand>>). Der
Buchstabe `i` bezeichnet ein installiertes Paket, `A` in der dritten
Spalte markiert ``automatisch installiert'' und deutet auf eine
automatisch erfüllte Paketabhängigkeit hin (siehe dazu
<<automatisch-installierte-pakete-anzeigen>>). Daneben sehen Sie in der
Ausgabe noch den Namen und die Kurzbeschreibung zum jeweiligen Paket.

.`aptitude` listet die installierten LaTeX-Pakete auf
----
$ aptitude search '~i' | grep texlive
i   texlive                         - TeX Live: Eine anständige Auswahl der TeX-
i A texlive-base                    - TeX Live: Grundlegende Programme und Datei
i A texlive-bibtex-extra            - TeX Live: Extra BibTeX styles
i A texlive-binaries                - Binärdateien für TeX Live
i A texlive-common                  - TeX Live: Basiskomponenten
i A texlive-doc-base                - TeX Live: Dokumentation für TeX Live
$
----

Geht es Ihnen nur um die Namen der installierten Pakete auf ihrem System, hilft 
folgende Kombination aus `aptitude`, `sed` und `awk` weiter:

.Paketliste mittels `aptitude` ausgeben
----
$ aptitude search '~i' | sed -E 's/i [A ]? //'| awk ' { print $1 } '
aapt
acl
acpi
adduser
adwaita-icon-theme
alsa-base
...
$
----

Die Angabe `-E 's/i [A ]? //' bei `sed` aktiviert zunächst erweiterte Reguläre 
Ausdrücke (Schalter `-E`) und ersetzt danach alle Vorkommen der Zeichenkette 
aus einem kleinen `i` gefolgt von einem Leerzeichen, einem möglichen `A` oder 
Leerzeichen sowie einem abschließenden Leerzeichen durch nichts (es löscht die
Zeichen aus der Zeile). Die Angabe von `' { print $1 } '` bei `awk` gibt danach
lediglich erste Spalte jeder Zeile aus, die den Paketnamen enthält. Alle 
weiteren Informationen, die `aptitude` bereitgestellt hatte, entfallen.

==== `apt list --installed` ====

// Stichworte für den Index
(((apt, list --installed)))

`apt` seit der Version 1.0 liefert ebenfalls einen Schalter `list`. Genauer
spezifizieren die installierten Pakete mit Hilfe der zusätzlichen Angabe 
`--installed`. Die Ausgabe sieht dann so aus:

.`apt` listet die installierten Pakete auf
----
$ apt list --installed

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

Auflistung...
aapt/oldstable,now 1:7.0.0+r33-1 amd64  [Installiert,automatisch]
acl/oldstable,now 2.2.52-3+b1 amd64  [installiert]
acpi/oldstable,now 1.7-1+b1 amd64  [installiert]
adduser/oldstable,now 3.115 all  [installiert]
adwaita-icon-theme/oldstable,now 3.22.0-1+deb9u1 all  [Installiert,automatisch]
...
$
----

Jede Zeile der obigen Ausgabe beinhaltet den Paketnamen, den Status der 
Veröffentlichung, die Versionsnummer, die Architektur und den Status der 
Installation. Um das weiter auf die Paketnamen einzugrenzen, helfen Ihnen 
wiederum die beiden Werkzeuge `awk` und `tail` weiter. `awk` filtert den
Paketnamen aus jeder Zeile heraus und `tail` entsorgt die ersten vier Zeilen
inklusive der Warnung. Die Angabe `2>1` hinter `apt` lenkt zuvor noch den 
Fehlerkanal `stderr` auf die Standardausgabe `stdout` um.

.`apt` listet die installierten Pakete auf (Paketliste)
----
$ apt list --installed 2>1 | awk -F '/' ' { print $1 } ' | tail +4 
aapt
acl
acpi
adduser
adwaita-icon-theme
...
$
----

==== Weitere Möglichkeiten ====

Graphische Programme wie beispielsweise Synaptic (siehe
<<gui-synaptic>>) und SmartPM (siehe <<gui-smartpm>>) verwenden
keine Buchstaben zur Kennzeichnung des Paketstatus, sondern nutzen
stattdessen verschiedenfarbige Kästchen (``Icons''). In
<<fig.smartpm-icons>> sehen Sie alle Möglichkeiten in der vollständigen
Übersicht. Installierte Pakete erkennen Sie an der grünen Farbe,
weiß/hellgrau kennzeichnet nicht installierte Pakete und rot steht hier
für defekte Pakete (Status ``broken'').

.Icons zur Darstellung des Paketstatus
image::werkzeuge/paketoperationen/smartpm-icons.png[id="fig.smartpm-icons", width="50%"]

// Datei (Ende): ./werkzeuge/paketoperationen/liste-der-installierten-pakete-anzeigen-und-deuten.adoc
