Nächste: , Nach oben: Entwicklung   [Inhalt][Index]


7.1 guix shell aufrufen

Der Zweck von guix shell ist, dass Sie Software-Umgebungen für außergewöhnliche Fälle einfach aufsetzen können, ohne dass Sie Ihr Profil ändern müssen. Normalerweise braucht man so etwas für Entwicklungsumgebungen, aber auch wenn Sie Anwendungen ausführen wollen, ohne Ihr Profil mit ihnen zu verunreinigen.

Anmerkung: Der Befehl guix shell wurde erst kürzlich eingeführt als Neuauflage von guix environment (siehe guix environment aufrufen). Wenn Sie mit guix environment vertraut sind, werden Sie die Ähnlichkeit bemerken, aber wir hoffen, der neue Befehl erweist sich als praktischer.

Die allgemeine Syntax lautet:

guix shell [Optionen] [Pakete…]

Manchmal will man keine interaktive Shell-Sitzung. Ein beliebiger Befehl kann aufgerufen werden, indem Sie nach Angabe der Pakete noch -- vor den gewünschten Befehl schreiben, um ihn von den übrigen Argumenten abzutrennen.

Folgendes Beispiel zeigt, wie Sie eine Umgebung erzeugen lassen, die Python und NumPy enthält, – jedes dazu fehlende Paket wird erstellt oder heruntergeladen –, und in der Umgebung dann python3 ausführen.

guix shell python python-numpy -- python3

Wir betonen, dass Sie auch das zu Grunde liegende python-Paket in dem Befehl angeben müssen, sogar wenn Python schon in Ihre Umgebung installiert ist. Das bewirkt, dass in der Shell-Umgebung PYTHONPATH und andere zugehörige Variable gesetzt werden können. Die Shell-Umgebung kann dafür nicht darauf zurückgreifen, was vorher in der Umgebung installiert war, weil es nichtdeterministisch wäre. Das gilt für die meisten Bibliotheken: Auch das zu deren Programmiersprache gehörige Paket muss im Shell-Aufruf angegeben werden.

Anmerkung: guix shell kann auch als Skript-Interpretierer dienen; man spricht auch von einem Shebang. Hier ist ein Beispiel, wie es in einem eigenständigen Python-Skript benutzt werden kann:

#!/usr/bin/env -S guix shell python python-numpy -- python3
import numpy
print("Hier spricht numpy", numpy.version.version)

Sie können beliebige Befehlszeilenoptionen auf diese Weise an guix shell übergeben, doch beachten Sie: Der Linux-Kernel beschränkt die Länge eines Shebangs auf maximal 127 Bytes.

Entwicklungsumgebungen erzeugen Sie wie im folgenden Beispiel, wo eine interaktive Shell gestartet wird, in der alle Abhängigkeiten und Variable vorliegen, die zur Arbeit an Inkscape nötig sind:

guix shell --development inkscape

Sobald er die Shell beendet, findet sich der Benutzer in der ursprünglichen Umgebung wieder, in der er sich vor dem Aufruf von guix shell befand. Beim nächsten Durchlauf des Müllsammlers (siehe guix gc aufrufen) dürfen Pakete von der Platte gelöscht werden, die innerhalb der Umgebung installiert worden sind und außerhalb nicht länger benutzt werden.

Um die Nutzung zu vereinfachen, wird guix shell, wenn Sie es interaktiv ohne Befehlszeilenargumente aufrufen, das bewirken, was es dann vermutlich soll. Also:

guix shell

Wenn im aktuellen Arbeitsverzeichnis oder irgendeinem übergeordneten Verzeichnis eine Datei manifest.scm vorkommt, wird sie so behandelt, als hätten Sie sie mit --manifest übergeben. Ebenso wird mit einer Datei guix.scm, wenn sie in selbigen Verzeichnissen enthalten ist, eine Entwicklungsumgebung hergestellt, als wären --development und --file beide angegeben worden. So oder so wird die jeweilige Datei nur dann geladen, wenn das Verzeichnis, in dem sie steckt, in ~/.config/guix/shell-authorized-directories aufgeführt ist. Damit lassen sich Entwicklungsumgebungen leicht definieren, teilen und betreten.

Vorgegeben ist, dass für die Shell-Sitzung bzw. den Befehl eine ergänzte Umgebung aufgebaut wird, in der die neuen Pakete zu Suchpfad-Umgebungsvariablen wie PATH hinzugefügt werden. Sie können stattdessen auch beschließen, eine isolierte Umgebung anzufordern mit nichts als den Paketen, die Sie angegeben haben. Wenn Sie die Befehlszeilenoption --pure angeben, werden alle Definitionen von Umgebungsvariablen aus der Elternumgebung gelöscht14. Wenn Sie --container angeben, wird die Shell darüber hinaus in einem Container vom restlichen System isoliert:

guix shell --container emacs gcc-toolchain

Dieser Befehl startet eine interaktive Shell in einem Container, der den Zugriff auf alles außer emacs, gcc-toolchain und deren Abhängigkeiten unterbindet. Im Container haben Sie keinen Netzwerkzugriff und es werden außer dem aktuellen Arbeitsverzeichnis keine Dateien mit der äußeren Umgebung geteilt. Das dient dazu, den Zugriff auf systemweite Ressourcen zu verhindern, wie /usr/bin auf Fremddistributionen.

Diese --container-Befehlszeilenoption kann sich aber auch als nützlich erweisen, um Anwendungen mit hohem Sicherheitsrisiko wie z.B. Webbrowser in eine isolierte Umgebung eingesperrt auszuführen. Folgender Befehl startet zum Beispiel Ungoogled-Chromium in einer isolierten Umgebung, für die gilt:

guix shell --container --network --no-cwd ungoogled-chromium \
  --preserve='^XAUTHORITY$' --expose="${XAUTHORITY}" \
  --preserve='^DISPLAY$' -- chromium

guix shell definiert die Variable GUIX_ENVIRONMENT in der neu erzeugten Shell. Ihr Wert ist der Dateiname des Profils dieser neuen Umgebung. Das könnten Nutzer verwenden, um zum Beispiel eine besondere Prompt als Eingabeaufforderung für Entwicklungsumgebungen in ihrer .bashrc festzulegen (siehe Bash Startup Files in Referenzhandbuch von GNU Bash):

if [ -n "$GUIX_ENVIRONMENT" ]
then
    export PS1="\u@\h \w [dev]\$ "
fi

… oder um ihr Profil durchzusehen:

$ ls "$GUIX_ENVIRONMENT/bin"

Im Folgenden werden die verfügbaren Befehlszeilenoptionen zusammengefasst.

--check

Hiermit wird die Umgebung angelegt und gemeldet, ob die Shell Umgebungsvariable überschreiben würde. Es ist eine gute Idee, diese Befehlszeilenoption anzugeben, wenn Sie zum ersten Mal guix shell zum Starten einer interaktiven Sitzung einsetzen, um sicherzugehen, dass Ihre Shell richtig eingestellt ist.

Wenn die Shell zum Beispiel den Wert der Umgebungsvariablen PATH ändert, meldet dies --check, weil Sie dadurch nicht die Umgebung bekämen, die Sie angefordert haben.

In der Regel sind solche Probleme ein Zeichen dafür, dass Dateien, die beim Start der Shell geladen werden, die Umgebungsvariablen unerwartet verändern. Wenn Sie zum Beispiel Bash benutzen, vergewissern Sie sich, dass Umgebungsvariable in ~/.bash_profile festgelegt oder geändert werden, nicht in ~/.bashrc – erstere Datei wird nur von Login-Shells mit „source“ geladen. Siehe Bash Startup Files in Referenzhandbuch zu GNU Bash für Details über beim Starten von Bash gelesene Dateien.

--development
-D

Lässt guix shell die Abhängigkeiten des danach angegebenen Pakets anstelle des Pakets in die Umgebung aufnehmen. Es kann mit anderen Paketen kombiniert werden. Zum Beispiel wird mit folgendem Befehl eine interaktive Shell gestartet, die die zum Erstellen nötigen Abhängigkeiten von GNU Guile sowie Autoconf, Automake und Libtool enthält:

guix shell -D guile autoconf automake libtool
--expression=Ausdruck
-e Ausdruck

Eine Umgebung für das Paket oder die Liste von Paketen erzeugen, zu der der Ausdruck ausgewertet wird.

Zum Beispiel startet dies:

guix shell -D -e '(@ (gnu packages maths) petsc-openmpi)'

eine Shell mit der Umgebung für eben diese bestimmte Variante des Pakets PETSc.

Wenn man dies ausführt:

guix shell -e '(@ (gnu) %base-packages)'

bekommt man eine Shell, in der alle Basis-Pakete verfügbar sind.

Die obigen Befehle benutzen nur die Standard-Ausgabe des jeweiligen Pakets. Um andere Ausgaben auszuwählen, können zweielementige Tupel spezifiziert werden:

guix shell -e '(list (@ (gnu packages bash) bash) "include")'

Siehe package->development-manifest, für Informationen, wie Sie die Entwicklungsumgebung für ein Paket in einem Manifest wiedergeben.

--file=Datei
-f Datei

Eine Umgebung erstellen mit dem Paket oder der Liste von Paketen, zu der der Code in der Datei ausgewertet wird.

Zum Beispiel könnte die Datei eine Definition wie diese enthalten (siehe Pakete definieren):

(use-modules (guix)
             (gnu packages gdb)
             (gnu packages autotools)
             (gnu packages texinfo))

;; Augment the package definition of GDB with the build tools
;; needed when developing GDB (and which are not needed when
;; simply installing it.)
(package
  (inherit gdb)
  (native-inputs (modify-inputs (package-native-inputs gdb)
                   (prepend autoconf-2.69 automake texinfo))))

Mit so einer Datei können Sie eine Entwicklungsumgebung für GDB betreten, indem Sie dies ausführen:

guix shell -D -f gdb-devel.scm
--manifest=Datei
-m Datei

Eine Umgebung für die Pakete erzeugen, die im Manifest-Objekt enthalten sind, das vom Scheme-Code in der Datei geliefert wird. Wenn diese Befehlszeilenoption mehrmals wiederholt angegeben wird, werden die Manifeste aneinandergehängt.

Dies verhält sich ähnlich wie die gleichnamige Option des Befehls guix package (siehe --manifest) und benutzt auch dieselben Manifestdateien.

Siehe Manifeste verfassen für Informationen dazu, wie man ein Manifest schreibt. Siehe --export-manifest im folgenden Text, um zu erfahren, wie Sie ein erstes Manifest erhalten.

--export-manifest

Auf die Standardausgabe ein Manifest ausgeben, das mit --manifest genutzt werden kann und den angegebenen Befehlszeilenoptionen entspricht.

Auf diese Weise können Sie die Argumente der Befehlszeile in eine Manifestdatei verwandeln. Nehmen wir an, Sie wären es leid, lange Befehlszeilen abzutippen, und hätten stattdessen lieber ein gleichbedeutendes Manifest:

guix shell -D guile git emacs emacs-geiser emacs-geiser-guile

Fügen Sie einfach --export-manifest zu der obigen Befehlszeile hinzu:

guix shell --export-manifest \
  -D guile git emacs emacs-geiser emacs-geiser-guile

… und schon sehen Sie ein Manifest, was so ähnlich aussieht:

(concatenate-manifests
  (list (specifications->manifest
          (list "git"
                "emacs"
                "emacs-geiser"
                "emacs-geiser-guile"))
        (package->development-manifest
          (specification->package "guile"))))

Diese Ausgabe können Sie in einer Datei speichern, nennen wir sie manifest.scm, die Sie dann an guix shell oder so ziemlich jeden beliebigen guix-Befehl übergeben:

guix shell -m manifest.scm

Na bitte. Aus der langen Befehlszeile ist ein Manifest geworden! Beim Verwandlungsvorgang werden Paketumwandlungsoptionen berücksichtigt (siehe Paketumwandlungsoptionen), d.h. er sollte verlustfrei sein.

--profile=Profil
-p Profil

Eine Umgebung mit den Paketen erzeugen, die im Profil installiert sind. Benutzen Sie guix package (siehe guix package aufrufen), um Profile anzulegen und zu verwalten.

--pure

Bestehende Umgebungsvariable deaktivieren, wenn die neue Umgebung erzeugt wird, mit Ausnahme der mit --preserve angegebenen Variablen (siehe unten). Dies bewirkt, dass eine Umgebung erzeugt wird, in der die Suchpfade nur Paketeingaben nennen und sonst nichts.

--preserve=Regexp
-E Regexp

Wenn das hier zusammen mit --pure angegeben wird, bleiben die zum regulären Ausdruck Regexp passenden Umgebungsvariablen erhalten – mit anderen Worten werden sie auf eine „weiße Liste“ von Umgebungsvariablen gesetzt, die erhalten bleiben müssen. Diese Befehlszeilenoption kann mehrmals wiederholt werden.

guix shell --pure --preserve=^SLURM openmpi … \
  -- mpirun …

In diesem Beispiel wird mpirun in einem Kontext ausgeführt, in dem die einzig definierten Umgebungsvariablen PATH und solche sind, deren Name mit ‘SLURM’ beginnt, sowie die üblichen besonders „kostbaren“ Variablen (HOME, USER, etc.).

--search-paths

Die Umgebungsvariablendefinitionen anzeigen, aus denen die Umgebung besteht.

--system=System
-s System

Versuchen, für das angegebene System zu erstellen – z.B. i686-linux.

--container
-C

Den Befehl in einer isolierten Umgebung (einem sogenannten „Container“) ausführen. Das aktuelle Arbeitsverzeichnis außerhalb des Containers wird in den Container zugeordnet. Zusätzlich wird, wenn es mit der Befehlszeilenoption --user nicht anders spezifiziert wurde, ein stellvertretendes persönliches Verzeichnis erzeugt, dessen Inhalt der des wirklichen persönlichen Verzeichnisses ist, sowie eine passend konfigurierte Datei /etc/passwd.

Der erzeugte Prozess läuft außerhalb des Containers als der momentane Nutzer. Innerhalb des Containers hat er dieselbe UID und GID wie der momentane Nutzer, außer die Befehlszeilenoption --user wird übergeben (siehe unten).

--network
-N

Bei isolierten Umgebungen („Containern“) wird hiermit der Netzwerk-Namensraum mit dem des Wirtssystems geteilt. Container, die ohne diese Befehlszeilenoption erzeugt wurden, haben nur Zugriff auf das Loopback-Gerät.

--link-profile
-P

Bei isolierten Umgebungen („Containern“) wird das Umgebungsprofil im Container als ~/.guix-profile verknüpft und ~/.guix-profile dann in GUIX_ENVIRONMENT gespeichert. Das ist äquivalent dazu, ~/.guix-profile im Container zu einer symbolischen Verknüpfung auf das tatsächliche Profil zu machen. Wenn das Verzeichnis bereits existiert, schlägt das Verknüpfen fehl und die Umgebung wird nicht hergestellt. Dieser Fehler wird immer eintreten, wenn guix shell im persönlichen Verzeichnis des Benutzers aufgerufen wurde.

Bestimmte Pakete sind so eingerichtet, dass sie in ~/.guix-profile nach Konfigurationsdateien und Daten suchen,15 weshalb --link-profile benutzt werden kann, damit sich diese Programme auch in der isolierten Umgebung wie erwartet verhalten.

--user=Benutzer
-u Benutzer

Bei isolierten Umgebungen („Containern“) wird der Benutzername Benutzer anstelle des aktuellen Benutzers benutzt. Der erzeugte Eintrag in /etc/passwd im Container wird also den Namen Benutzer enthalten und das persönliche Verzeichnis wird den Namen /home/BENUTZER tragen; keine GECOS-Daten über den Nutzer werden in die Umgebung übernommen. Des Weiteren sind UID und GID innerhalb der isolierten Umgebung auf 1000 gesetzt. Benutzer muss auf dem System nicht existieren.

Zusätzlich werden alle geteilten oder exponierten Pfade (siehe jeweils --share und --expose), deren Ziel innerhalb des persönlichen Verzeichnisses des aktuellen Benutzers liegt, relativ zu /home/BENUTZER erscheinen, einschließlich der automatischen Zuordnung des aktuellen Arbeitsverzeichnisses.

# wird Pfade als /home/foo/wd, /home/foo/test und /home/foo/target exponieren
cd $HOME/wd
guix shell --container --user=foo \
     --expose=$HOME/test \
     --expose=/tmp/target=$HOME/target

Obwohl dies das Datenleck von Nutzerdaten durch Pfade im persönlichen Verzeichnis und die Benutzereinträge begrenzt, kann dies nur als Teil einer größeren Lösung für Datenschutz und Anonymität sinnvoll eingesetzt werden. Es sollte nicht für sich allein dazu eingesetzt werden.

--no-cwd

In isolierten Umgebungen („Containern“) ist das vorgegebene Verhalten, das aktuelle Arbeitsverzeichnis mit dem isolierten Container zu teilen und in der Umgebung sofort in dieses Verzeichnis zu wechseln. Wenn das nicht gewünscht wird, kann das Angeben von --no-cwd dafür sorgen, dass das Arbeitsverzeichnis nicht automatisch geteilt wird und stattdessen in das Persönliche Verzeichnis („Home“-Verzeichnis) gewechselt wird. Siehe auch --user.

--expose=Quelle[=Ziel]
--share=Quelle[=Ziel]

Bei isolierten Umgebungen („Containern“) wird das Dateisystem unter Quelle vom Wirtssystem als Nur-Lese-Dateisystem Ziel (bzw. für --share auch mit Schreibrechten) im Container zugänglich gemacht. Wenn kein Ziel angegeben wurde, wird die Quelle auch als Ziel-Einhängepunkt in der isolierten Umgebung benutzt.

Im folgenden Beispiel wird eine Guile-REPL in einer isolierten Umgebung gestartet, in der das persönliche Verzeichnis des Benutzers als Verzeichnis /austausch nur für Lesezugriffe zugänglich gemacht wurde:

guix shell --container --expose=$HOME=/austausch guile -- guile
--symlink=Spezifikation
-S Spezifikation

Für Container werden hiermit die in der Spezifikation angegebenen symbolischen Verknüpfungen hergestellt. Siehe die Dokumentation in pack-symlink-option.

--emulate-fhs
-F

Wenn Sie dies zusammen mit --container angeben, wird im Container eine Konfiguration emuliert, die dem Filesystem Hierarchy Standard (FHS) folgt, so dass es /bin, /lib und weitere Verzeichnisse gibt, wie es der FHS vorschreibt.

Obwohl Guix vom FHS-Standard abweicht, kann das System in Ihrem Container mit dieser Befehlszeilenoption zu anderen GNU/Linux-Distributionen ähnlicher werden. Dadurch lassen sich dortige Entwicklungsumgebungen reproduzieren und Sie können Programme testen und benutzen, die das Befolgen des FHS-Standards voraussetzen. Wenn die Option angegeben wird, enthält der Container eine Version von glibc, die die im Container befindliche /etc/ld.so.cache als Zwischenspeicher gemeinsamer Bibliotheken ausliest (anders als glibc im normalen Gebrauch von Guix), und die im FHS verlangten Verzeichnisse /bin, /etc, /lib und /usr werden aus dem Profil des Containers übernommen.

--nesting
-W

Wenn Sie dies zusammen mit --container angeben, wird Guix im Container verfügbar gemacht, so dass man sich von innerhalb mit dem Erstellungs-Daemon verbinden kann, der außerhalb des Containers läuft. Das können Sie gebrauchen, wenn Sie vom isolierten Container aus wiederum andere Container erzeugen lassen können wollen wie in dieser Beispielsitzung:

$ guix shell -CW coreutils
[env]$ guix shell -C guile -- guile -c '(display "Hallo!\n")'
Hallo!
[env]$ exit

In der Sitzung wird ein Container gestartet, in dem die coreutils-Programme in PATH zur Verfügung stehen. Von da aus legen wir mit guix shell einen inneren, verschachtelten Container an, der außer Guile nichts verfügbar macht.

Ein weiteres Anwendungsbeispiel ist, wenn Sie eine guix.scm auswerten möchten, der Sie nicht vertrauen, wie hier:

guix shell -CW -- guix build -f guix.scm

Durch einen so durchgeführten Befehl guix build sind nur Zugriffe auf Ihr aktuelles Arbeitsverzeichnis möglich.

Intern werden für die Befehlszeilenoption -W mehrere Einstellungen vorgenommen:

  • Der Socket für den Daemon (in der Vorgabeeinstellung ist das /var/guix/daemon-socket/socket) wird im Container verfügbar gemacht.
  • Der gesamte Store (in der Vorgabeeinstellung ist das /gnu/store) wird im Container verfügbar gemacht, damit auf Store-Objekte von verschachtelten guix-Aufrufen zugegriffen werden kann.
  • Der aktuell benutzte guix-Befehl wird zum Profil innerhalb des Containers hinzugefügt, so dass guix describe innerhalb und außerhalb des Containers den gleichen Zustand ausgibt.
  • Der Zwischenspeicher (in der Vorgabeeinstellung ist das ~/.cache/guix) des Wirtssystems wird mit Schreibzugriff zugänglich gemacht. Dadurch können Befehle wie guix time-machine und guix shell effizient ablaufen.
--rebuild-cache

In der Regel wird guix shell die Umgebung zwischenspeichern, damit weitere Aufrufe sie ohne Verzögerung verwenden können. Am längsten nicht verwendete („least recently used“) Einträge im Zwischenspeicher werden bei guix shell regelmäßig entfernt. Auch wenn Sie --file oder --manifest nutzen, wird der Zwischenspeicher ungültig, sobald die entsprechende Datei geändert wurde.

Mit der Befehlszeilenoption --rebuild-cache wird die zwischengespeicherte Umgebung erneuert. Sie können --rebuild-cache verwenden, wenn Sie --file oder --manifest nutzen und die Datei guix.scm oder manifest.scm auf externe Abhängigkeiten verweist oder eine andere Umgebung ergeben sollte, wenn sich zum Beispiel Umgebungsvariable geändert haben.

--root=Datei
-r Datei

Die Datei zu einer symbolischen Verknüpfung auf das Profil dieser Umgebung machen und als eine Müllsammlerwurzel registrieren.

Das ist nützlich, um seine Umgebung vor dem Müllsammler zu schützen und sie „persistent“ zu machen.

Wenn diese Option weggelassen wird, wird das Profil von guix shell zwischengespeichert, damit weitere Aufrufe es ohne Verzögerung verwenden können. Das ist vergleichbar damit, wenn Sie --root angeben, jedoch wird guix shell die am längsten nicht verwendeten Müllsammlerwurzeln („least recently used“) regelmäßig entfernt.

In manchen Fällen wird guix shell keinen Zwischenspeicher für die Profile anlegen, z.B. wenn Umwandlungsoptionen wie --with-latest angegeben wurde. Das bedeutet, die Umgebung ist nur, solange die Sitzung von guix shell besteht, vor dem Müllsammler sicher. Dann müssen Sie, wenn Sie das nächste Mal dieselbe Umgebung neu erzeugen, vielleicht Pakete neu erstellen oder neu herunterladen.

guix gc aufrufen hat mehr Informationen über Müllsammlerwurzeln.

guix shell unterstützt auch alle gemeinsamen Erstellungsoptionen, die von guix build unterstützt werden (siehe Gemeinsame Erstellungsoptionen), und die Paketumwandlungsoptionen (siehe Paketumwandlungsoptionen).


Fußnoten

(14)

Denken Sie daran, wenn Sie das erste Mal guix shell interaktiv benutzen, mit der Befehlszeilenoption --check zu prüfen, dass die Shell-Einstellungen die Wirkung von --pure nicht wieder zurücknehmen.

(15)

Zum Beispiel inspiziert das Paket fontconfig das Verzeichnis ~/.guix-profile/share/fonts, um zusätzliche Schriftarten zu finden.


Nächste: guix environment aufrufen, Nach oben: Entwicklung   [Inhalt][Index]