// Datei: ./praxis/alternatives/alternatives.adoc

// Baustelle: Fertig

[[alternatives]]
== Alternative Standard-Programme mit Debians Alternativen-System ==

// Stichworte für den Index
(((Debians Alternativen-System)))
(((freedesktop.org)))
(((X Desktop Group)))
(((XDG)))
Moderne Benutzeroberflächen regeln die Auswahl des Standard-Webbrowsers
und des Standard-Editors über XDG{empty}footnote:[X Desktop Group (XDG), seit
dem Jahr 2000 freedesktop.org]. Die Basis dafür bildet die Zuordnung der
Anwendungen über MIME (engl. 'MIME Applications Associations')
<<mime-applications-associations>> und im Speziellen die Liste der
Standardanwendungen (engl. 'Default Applications')
<<mime-applications-associations-default-applications>>. Zur
Konfiguration steht Ihnen meist eine passende graphische Oberfläche zur
Verfügung.

// Stichworte für den Index
(((Debianpaket, sensible-utils)))
(((select-editor)))
(((sensible-browser)))
(((sensible-editor)))
(((sensible-pager)))
(((x-www-browser)))
Ähnliches leisten die Programme `select-editor`, `sensible-browser`,
`sensible-editor` und `sensible-pager` aus dem Paket 'sensible-utils'
<<Debian-Paket-sensible-utils>>. Diese werten primär die
Umgebungsvariablen wie `$EDITOR`, `$BROWSER` und `$PAGER` aus und leiten
daraus die Programmauswahl ab. Viele Einzelanwendungen, die wiederum
andere Standardprogramme aufrufen, ermitteln bspw. die Information nicht
selbst, welchen Editor Sie als Benutzer bevorzugen und verwenden. Sie
verlassen sich stattdessen auf die Rückgabewerte, die Ihnen an dieser
Stelle vom Werkzeug `sensible-editor` geliefert werden. Gleiches gilt
für die anderen drei Werkzeuge.

Ebenso funktioniert das auch in Ihrem Terminal. Rufen Sie darin die
Programme namens `editor` oder `x-www-browser` auf, werden ebenfalls
diese Variablen ausgewertet und das darüber referenzierte Werkzeug
ausgeführt.

Leider funktionieren diese beiden o.g. Arten der Auswahl des
Standardprogramms nicht für alle Einsatzzwecke, sei es, weil es keinen
passenden MIME-Typ für eine bestimmte Aufgabe gibt -- z.B. das
Standard-Desktop-Hintergrundbild -- oder weil niemand bislang eine
allgemein gültige Umgebungsvariable dafür definiert hat. Letzteres
betrifft bspw. das Ballerspiel Doom, für das mehrere, unterschiedliche
Spieleengines verfügbar sind.

Aus diesem Grund ermöglicht Debian Ihnen als Systembetreuer zusätzlich
zu den bereits vorher beschriebenen Varianten auch noch die Festlegung
eines sinnvollen Standardprogramms über das Debian Alternativen-System.
Basierend auf den lokal installierten Werkzeugen legen Sie dieses
Standardprogramm manuell fest oder lassen dieses automatisch auswählen.

Das Alternativen-System ist eine Debian-Eigenheit, die für viele
Programme und -Pakete existiert. In RedHat/Fedora wurde das System in
leicht veränderter Form übernommen <<Debian-Wiki-Alternatives>>. Ubuntu
präferiert hingegen XDG und greift vor allem dann auf das Debian
Alternativen-System zurück, wenn es die Pakete unverändert von Debian
übernimmt.

// Stichworte für den Index
(((Debianpaket, galternatives)))
(((Debians Alternativen-System, Prioritäten)))
(((galternatives)))
(((Konfigurationsdatei, /etc/alternatives/)))
(((update-alternatives)))
Es basiert auf symbolischen Verweisen (kurz 'Symlink') nach und in das
Verzeichnis `/etc/alternatives/` sowie gemäß der vom Paketbetreuer zuvor
festgelegten Priorität pro Alternative. Folgen Sie den Vorgaben, wird
dabei stets das Programm ausgeführt, welchem die höchste Priorität
zugeordnet ist. Eine manuelle Festlegung hebt die Vorgaben auf.

Das Werkzeug zur Verwaltung dieser Symlinks auf der Kommandozeile heißt
`update-alternatives`, für die graphische Benutzerschnittstelle steht
Ihnen 'galternatives' aus dem gleichnamigen Paket bereit
<<Debian-Paket-galternatives>>. In <<fig.galternatives>> sehen Sie
exemplarisch die Möglichkeiten für die Gruppe `x-www-browser`.

.Auswahl mit Hilfe des Programms 'galternatives'
image::praxis/alternatives/galternatives.png[id="fig.galternatives", width="50%"]

=== Hintergrund: Warum alternative Standardprogramme? ===

In Debian stellen mehrere Programme bzw. Pakete eine ähnliche oder
gleiche Fähigkeit bereit. Damit entscheiden Sie, welches Werkzeug zum
Einsatz kommt. Ubuntu fährt hier eine wesentlich restriktivere Politik.

Das betrifft auf der einen Seite sehr generische Funktionalitäten wie
z.B. die eines Webbrowsers, eines (Text-)Editors oder eines Pagers, aber
auch sehr spezifische Funktionalitäten, für die einfach mehrere
Implementierungen vorliegen. Zu Letzteren gehören bspw. das Schweizer
Taschenmesser für TCP/IP namens `netcat` oder die Skriptsprache `awk`.
Letztere liegt in drei Varianten vor -- in der eher umfangreicheren
Implementation des GNU Projektes (`gawk`), in der kleineren und
schnelleren Implementation von Mike Brennan (`mawk`) und in der
originalen Awk-Implementation <<awk>>.

Weiterhin gibt es in Debian von einigen Programmen mehr als eine
Programmgeneration.

In Debian 8 _Jessie_ gibt z.B. verschiedene Veröffentlichungen von GCC
und Automake. GCC ist in den beiden Versionen 4.8 und 4.9 enthalten
und Automake in den Versionen 1.11 und 1.14. Einer der Gründe für die
verschiedenen Versionen ist, dass manche Pakete in Debian z.B.  nur
mit einer bestimmten Generation eines Compilers übersetzt werden
können. So werden z.B. in Debian 8 _Jessie_ alle Linuxkernel mit GCC 4.8
kompiliert, während GCC 4.9 der Standardcompiler ist. Je nach
Einsatzzweck eines Systems kann es entsprechend auch hilfreich sein, den
Standardcompiler systemweit auf eine bestimmte Generation festzulegen.

In Debian 9 _Stretch_ ist dagegen GCC wieder nur noch in einer Version
enthalten, nämlich 6.3.0. Dafür ist OpenSSL hingegen in zwei
verschiedenen Versionen enthalten -- 1.1.0 und 1.0.2. Hintergrund ist
hier, dass bestimmte Programme (noch) nicht sauber mit der neueren
OpenSSL-Version kompiliert werden können und die dazu notwendigen
Änderungen nicht-trivial sind. So ist z.B. Apache gegen OpenSSL 1.0.2
gelinkt, weil noch nicht alle SSL-nutzenden Apache-Module sauber mit
OpenSSL 1.1 zusammenarbeiten. Eine Standard-Version in dem Sinne, wie es
sie beim GCC gibt, existiert hier jedoch nicht. Gegen welche
OpenSSL-Version ein Programm kompiliert und später gelinkt wird, hängt
davon ab, welches der beiden sich gegenseitig ausschließenden Pakete
`libssl-dev` (OpenSSL 1.1) oder `libssl1.0-dev` (OpenSSL 1.0.2)
installiert ist.

Ein weiterer Grund für die Verwendung des Alternativen-Systems
innerhalb desselben Binärpakets oder von Binärpaketen auf der Basis
desselben Sourcepakets sind unterschiedliche Konfigurationen oder
variierende Abhängigkeiten. Beispiel eins ist GNU Emacs, welcher in drei
Varianten vorliegt:

* basierend auf dem Gimp Tool Kit (GTK+) und mit voller
Unterstützung moderner Desktops (`emacs23` bzw. `emacs24`). Dieses Paket
hängt u.a. von D-Bus ab.
* basierend auf dem schlankeren Lucid-Toolkit (`emacs23-lucid` bzw.
`emacs24-lucid`). Mit Unterstützung für das X-Window-System, aber ohne
allzuviele sonstige Abhängigkeiten.
* ganz ohne graphische Benutzeroberfläche (`emacs23-nox` bzw. `emacs24-nox`).

Ein zweites Beispiel ist der Windowmanager `dwm`, bei welchem die
Konfiguration zum Kompilierzeitpunkt festgelegt wird. Das Paket 'dwm'
<<Debian-Paket-dwm>> enthält daher vier Programme mit einer jeweils
unterschiedlichen Konfiguration -- `dwm.default`, `dwm.maintainer`,
`dwm.web` und `dwm.winkey`. Über das Alternativen-System legen Sie fest,
welches davon verwendet wird, wenn Sie lediglich `dwm` aufrufen.

Viele Administratoren haben zudem sehr genaue Vorstellungen, welche
Programme verwendet werden sollten, wenn sie unter dem generischen
Programmnamen aufgerufen werden.

=== Standardprogramme anzeigen ===

// Stichworte für den Index
(((update-alternatives, --get-selections)))
Mit dem Aufruf `update-alternatives --get-selections` listen Sie alle
generischen Programme oder Dateien auf, für die es Alternativen auf
Ihrem lokalen System gibt. Ebenfalls mit ausgegeben werden dabei die
aktuell ausgewählte Alternative sowie die konkrete Auswahlform --
automatisch anhand der installierten Pakete und Prioritäten oder manuell
durch den lokalen Administrator.

.Beispielausgabe{empty}footnote:[von Axels Thinkpad und mit einer durchaus nicht ganz üblichen Auswahl] von `update-alternatives --get-selections` (massiv gekürzt)
----
$ update-alternatives --get-selections
automake                       auto     /usr/bin/automake-1.14
awk                            auto     /usr/bin/gawk
c++                            auto     /usr/bin/g++
c89                            auto     /usr/bin/c89-gcc
c99                            auto     /usr/bin/c99-gcc
cc                             auto     /usr/bin/gcc
cpp                            auto     /usr/bin/cpp
csh                            auto     /bin/bsd-csh
de.multi                       manual   /usr/lib/aspell/de-alt.multi
desktop-background             auto     /usr/share/images/desktop-base/lines-wallpaper_1920x1080.svg
desktop-background.xml         auto     /usr/share/images/desktop-base/lines.xml
desktop-grub                   auto     /usr/share/images/desktop-base/lines-grub.png
desktop-splash                 auto     /usr/share/images/desktop-base/spacefun-splash.svg
doom                           auto     /usr/games/chocolate-doom
dwm                            auto     /usr/bin/dwm.default
editor                         manual   /usr/bin/zile
emacs                          auto     /usr/bin/emacs24-x
emacsclient                    auto     /usr/bin/emacsclient.emacs24
ex                             auto     /usr/bin/nex
gnome-text-editor              auto     /usr/bin/leafpad
gnome-www-browser              auto     /usr/bin/opera
html2markdown                  auto     /usr/bin/html2markdown.py2
infobrowser                    auto     /usr/bin/info
jar                            auto     /usr/bin/fastjar
java                           auto     /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java
ksh                            auto     /bin/ksh93
locate                         auto     /usr/bin/mlocate
mp3-decoder                    auto     /usr/bin/mpg321
nc                             manual   /bin/nc.traditional
pager                          auto     /bin/less
rcp                            auto     /usr/bin/scp
rename                         auto     /usr/bin/file-rename
rlogin                         auto     /usr/bin/slogin
rsh                            auto     /usr/bin/ssh
rxvt                           manual   /usr/bin/urxvt
ssh-askpass                    manual   /usr/bin/ssh-askpass-fullscreen
telnet                         auto     /usr/bin/telnet-ssl
unison                         auto     /usr/bin/unison-latest-stable
unison-gtk                     auto     /usr/bin/unison-latest-stable-gtk
vi                             manual   /usr/bin/nvi
view                           manual   /usr/bin/nview
wesnoth                        auto     /usr/games/wesnoth-1.10
www-browser                    auto     /usr/bin/links2
x-cursor-theme                 manual   /etc/X11/cursors/crystalwhite.theme
x-session-manager              auto     /usr/bin/choosewm
x-terminal-emulator            manual   /usr/bin/uxterm
x-window-manager               manual   /usr/bin/ratpoison
x-www-browser                  manual   /usr/bin/conkeror
$
----

// Stichworte für den Index
(((update-alternatives, --list)))
Welche Alternativen für ein generisches Kommando verfügbar sind,
erfahren Sie mit dem Schalter `--list`. Nachfolgend sehen Sie das für
die Skriptsprache Awk.

.Ausgabe der verfügbaren Alternativen für die Skriptsprache Awk
----
$ update-alternatives --list awk
/usr/bin/gawk
/usr/bin/mawk
/usr/bin/original-awk
$
----

// Stichworte für den Index
(((update-alternatives, --display)))
Über den Schalter `--display` erfahren Sie die derzeit festgelegte
Alternative für ein generisches Kommando mitsamt den verfügbaren,
weiteren Möglichkeiten und allen ebenfalls umgebogenen Referenzen auf
dessen 'Slaves'. 'Slaves' sind weitere Dateien, die zu einem Programm
dazugehören, bspw. die passenden Handbuchseiten ('Manual Pages'). Anhand
des nachfolgenden Beispiels zu Awk verdeutlichen wir Ihnen das.

.Ausgabe der ausgewählten und verfügbaren Alternativen für Awk
----
$ update-alternatives --display awk
awk - automatischer Modus
  Link verweist zur Zeit auf /usr/bin/gawk
/usr/bin/gawk - Priorität 10
  Slave awk.1.gz: /usr/share/man/man1/gawk.1.gz
  Slave nawk: /usr/bin/gawk
  Slave nawk.1.gz: /usr/share/man/man1/gawk.1.gz
/usr/bin/mawk - Priorität 5
  Slave awk.1.gz: /usr/share/man/man1/mawk.1.gz
  Slave nawk: /usr/bin/mawk
  Slave nawk.1.gz: /usr/share/man/man1/mawk.1.gz
/usr/bin/original-awk - Priorität 0
  Slave awk.1.gz: /usr/share/man/man1/original-awk.1.gz
Gegenwärtig »beste« Version ist »/usr/bin/gawk«.
$
----

// Stichworte für den Index
(((update-alternatives, --query)))

[NOTE]
.Alternative Darstellung
========================================================
Benötigen Sie stattdessen eine maschinenlesbare Ausgabe, hilft Ihnen in
diesem Fall der Schalter `--query` weiter. Dabei werden die Blöcke in
einer an den RFC 822 <<RFC822>> angelehnten Weise formatiert und
zwischen den einzelnen Blöcken zusätzliche Leerzeilen eingefügt.
========================================================

=== Standardprogramm ändern ===

// Stichworte für den Index
(((update-alternatives, --config)))
Ist nur ein Paket installiert, welches für ein generisches Programm
eine einzige Alternative anbietet, so wird automatisch dieses verwendet
und es gibt keine Auswahl zur Konfiguration.

.Hinweis, falls für ein generisches Programm nur eine Alternative installiert ist.
----
# update-alternatives --config emacs
Es gibt nur eine Alternative in Link-Gruppe emacs (die /usr/bin/emacs
bereitstellt): /usr/bin/emacs24-x
Nichts zu konfigurieren.
#
----

Installieren Sie hingegen mehrere Pakete, die alle eine Alternative für
ein bestimmtes generisches Programm anbieten, so wird ohne weitere
Interaktion die Alternative ausgewählt, für die die höchste Priorität
vergeben wurde. Die Priorität legt der Paketmaintainer fest. Für manche
Gruppen von Alternativen gibt es jedoch feste Regeln zur Berechnung der
Prioritäten, so z.B. für Window-Manager. Diese sind in Abschnitt 11.8.4
des Debian Policy Manuals festgelegt <<Debian-Policy-Manual>>.
Installieren Sie bspw. `vim-gtk` auf einem System, auf dem bisher `nano`
der Editor mit der höchsten Priorität war, so werden bspw. die Datei
`/usr/bin/editor` und `/etc/alternatives/editor`
automatisch auf die graphische Variante von Vim umgestellt.

.Hinweise über die automatische Auswahl von Alternativen bei der Paketinstallation
----
[...]
Setting up vim-gtk (2:7.4.488-4) ...
update-alternatives: using /usr/bin/vim.gtk to provide /usr/bin/vim (vim) in auto mode
update-alternatives: using /usr/bin/vim.gtk to provide /usr/bin/vimdiff (vimdiff) in auto mode
update-alternatives: using /usr/bin/vim.gtk to provide /usr/bin/rvim (rvim) in auto mode
update-alternatives: using /usr/bin/vim.gtk to provide /usr/bin/rview (rview) in auto mode
update-alternatives: using /usr/bin/vim.gtk to provide /usr/bin/ex (ex) in auto mode
update-alternatives: using /usr/bin/vim.gtk to provide /usr/bin/editor (editor) in auto mode
update-alternatives: using /usr/bin/vim.gtk to provide /usr/bin/gvim (gvim) in auto mode
update-alternatives: using /usr/bin/vim.gtk to provide /usr/bin/gview (gview) in auto mode
update-alternatives: using /usr/bin/vim.gtk to provide /usr/bin/rgview (rgview) in auto mode
update-alternatives: using /usr/bin/vim.gtk to provide /usr/bin/rgvim (rgvim) in auto mode
update-alternatives: using /usr/bin/vim.gtk to provide /usr/bin/evim (evim) in auto mode
update-alternatives: using /usr/bin/vim.gtk to provide /usr/bin/eview (eview) in auto mode
update-alternatives: using /usr/bin/vim.gtk to provide /usr/bin/gvimdiff (gvimdiff) in auto mode
[...]
----

Die präferierte Alternative für ein gegebenes generisches Programm
ändern Sie mit der Option `--config`. Dabei entscheiden Sie auch, ob bei
zukünftigen Paketinstallationen die von Ihnen präferierte Alternative
automatisch neu ausgewählt werden soll, oder ob die manuell ausgewählte
Alternative stets beibehalten werden soll. Damit behalten Sie die
derzeit ausgewählte Alternative unverändert bei.

.Ändern des systemweiten Standardeditors von einer automatischen Wahl auf `zile`
----
$ update-alternatives --config editor
Es gibt 10 Auswahlmöglichkeiten für die Alternative editor (welche
/usr/bin/editor bereitstellen).

  Auswahl      Pfad              Priorität Status
- ----------------------------------------------------------
* 0            /usr/bin/vim.gtk   50        automatischer Modus
  1            /bin/ed           -100       manueller Modus
  2            /bin/elvis-tiny    10        manueller Modus
  3            /bin/nano          40        manueller Modus
  4            /usr/bin/emacs24   0         manueller Modus
  5            /usr/bin/mcedit    25        manueller Modus
  6            /usr/bin/nvi       19        manueller Modus
  7            /usr/bin/vigor    -150       manueller Modus
  8            /usr/bin/vim.gtk   50        manueller Modus
  9            /usr/bin/vim.nox   40        manueller Modus
  10           /usr/bin/zile      30        manueller Modus

Drücken Sie die Eingabetaste, um die aktuelle Wahl[*] beizubehalten,
oder geben Sie die Auswahlnummer ein: 10
update-alternatives: /usr/bin/zile wird verwendet, um /usr/bin/editor
(editor) im manuellen Modus bereitzustellen
$
----

Bei manchen Paketen wurde dem Prioritätswert mit einem Augenzwinkern
sogar noch eine zusätzliche Bedeutung untergeschoben. So zeigen zum
Beispiel die Prioritätswerte für die deutschsprachigen Wörterbücher
aus den Paketen 'aspell-de' und 'aspell-de-alt' gleichzeitig auch das
Jahr an, in welchem die entsprechende Reform der Rechtschreibung in
Kraft trat.

.Beispiel mit viel Humor in den deutschsprachigen 'aspell'-Wörterbüchern
----
There are 2 choices for the alternative de.multi (providing /usr/lib/aspell/de.multi).

  Selection    Path                          Priority   Status
- ----------------------------------------------------------
  0            /usr/lib/aspell/de-neu.multi   1996      auto mode
* 1            /usr/lib/aspell/de-alt.multi   1901      manual mode
  2            /usr/lib/aspell/de-neu.multi   1996      manual mode
----


// ToDo:
// Notizen zum Alternatives-System in Ubuntu:
//
// https://bugs.launchpad.net/ubuntu/+source/firefox/+bug/538912
// https://bugs.launchpad.net/ubuntu/+source/sensible-utils/+bug/204858
// https://help.ubuntu.com/community/WebBrowsers
//
// Benutzt Ubuntu nun dieses System offiziell nicht und dann doch oder
// umgekehrt?


// Datei (Ende): ./praxis/alternatives/alternatives.adoc
