GNU Stow

Aus wiki.archlinux.de

GNU Stow ist ein „Symlinkfarm-Manager“, mit dem es möglich ist, Dateien und Verzeichnisse aus verschiedenen Pfaden an einem Ort zu verwalten. Das Programm wird meistens dazu verwendet, um Dotfiles gesammelt in einem Verzeichnis zu haben um sie einfacher mittels Git versionieren zu können.

Installation

GNU Stow ist als stow in extra verfügbar, und kann von dort mittels Pacman installiert werden.

# GNU Stow an sich
pacman -S stow

# Für die Versionierung
pacman -S git

Mittels des Befehls stow lässt sich GNU Stow dann aufrufen.

Verhalten von stow

Standardmäßig benutzt GNU Stow das aktuelle Verzeichnis als Stow Directory, aus dem heraus die Packages ausgerollt werden. Zum Ausrollen wird standardmäßig das Elternverzeichnis benutzt. Wenn also zum Beispiel /home/user/.dotfiles als Stow Directory benutzt wird, ist das Target Directory automatisch /home/user/.

Diese Konfiguration lässt sich mittels der Parameter --dir (das Stow Directory) und --target (für das Target Directory) anpassen. Wenn nur --dir angegeben wird, wird als Target Directory automatisch das Elternverzeichnis des angegebenen Verzeichnisses benutzt.

Der Einfachheit halber kann man sich hier auch einen Alias setzen, wenn man sowieso nur seine Dotfiles verwalten will.

alias stow="/usr/bin/stow --dir /home/user/.config/dotfiles --target /home/user"

Hiermit wird /home/user/.config/dotfiles als Stow Directory benutzt in dem die Packages liegen, und /home/user ist das Target Directory in dem „gearbeitet wird“, wo also die Symlinks angelegt werden die durch GNU Stow verwaltet werden.

Alternativ kann im gewünschten Stow Directory eine Datei angelegt werden, in der Konfigurationsoptionen abgelegt werden können. Vor dem Aufruf von stow muss man dann in das Verzeichnis wechseln. Dies ermöglicht die einfachere Verwaltung verschiedener Stow Directorys.

/home/user/.config/dotfiles/.stowrc
--dir /home/user/.config/dotfiles
--target /home/user

Dies hat den selben Effekt wie der beschriebene Alias, sofern man vor dem Aufruf ins Verzeichnis /home/user/.config/dotfiles/ wechselt.

Wenn im Stow Directory ausschließlich Dotfiles verwaltet werden sollen, so kann man noch den Parameter --dotfiles übergeben. Dieser erlaubt es, Dotfiles „sichtbar“ in den Packages abzulegen. Dateien und Verzeichnisse auf der oberen Ebene müssen damit nicht als .irgendwas abgelegt werden, sondern können als dot-irgendwas abgelegt werden, was dafür sorgt, dass man nicht lauter „leere“ Verzeichnisse als Packages hat.

Die Beispiele im Wiki gehen davon aus, dass entweder per Alias oder per .stowrc das Target Directory als ~/ konfiguriert wird.

Dateien Verwalten

Die Verwaltung von Dateien erfolgt innerhalb von GNU Stow in Packages, dies sind einfache Verzeichnisse auf oberer Ebene innerhalb des Stow Directorys. Innerhalb dieser Packages werden die Dateien als Installation Image verwaltet. Ein Installation Image ist dabei die Struktur an Dateien und Verzeichnissen, wie sie später im Target Directory vorhanden sein soll.

Dass Anlegen eines Stow Directorys zur Verwaltung von Dotfiles:

mkdir ~/.config/dotfiles      # Verzeichnis erstellen ...
cd ~/.config/dotfiles         # ... und reinwechseln
echo '--dotfiles' >> .stowrc  # zusätzlich den Parameter --dotfiles setzen

Damit ist die Grundlage geschaffen, die Dotfiles zu verwalten. Es müssen nun die entsprechenden Packages erstellt werden, die man später verwenden möchte, um die Dotfiles auszurollen. Hier kann man entweder auf Programmebene arbeiten, und die Dotfiles eines jeden Programms separat erfassen, oder aber die Installation Images so erstellen, dass mehrere Dinge zusammengefasst werden.

Dateien stow-en

Hier werden zwei Packages angelegt, und das Installation Image schon mal derart vorbereitet, dass .config angelegt wird, wohin später Teile der Konfiguration verschoben werden.

mkdir multimedia/dot-config
mkdir terminal/dot-config

An dieser Stelle kann nun die gewünschten Konfiguration angelegt werden. Es werden Beispielhaft die Konfigurationsdateien von mpv, yt-dlp, Alacritty, und der zsh in die Packages verschoben.

mv ~/.config/mpv multimedia/dot-config/
mv ~/.config/yt-dlp multimedia/dot-config/
mv ~/.config/alacritty terminal/dot-config
mv ~/.config/.zshrc terminal/dot-zshrc

Daraus ergibt sich entsprechend folgende Struktur.

~/.config/dotfiles
├── multimedia
│   └── dot-config
│       ├── mpv
│       │   ├── input.conf
│       │   └── mpv.conf
│       └── yt-dlp
│           └── config
└── terminal
    ├── dot-config
    │   └── alacritty
    │       └── alacritty.toml
    └── dot-zshrc

Dies kann für weitere Dateien in beliebig vielen Packages fortgeführt werden.

Packages bereitstellen und zurückziehen

Um die Dateien nun als Konfiguration zu benutzen, muss man die entsprechenden Packages nur noch bereitstellen. Dies geschieht, indem man einfach den gewünschten Paketnamen angibt.

cd ~/.config/dotfiles  # Ins Verzeichnis wechseln
stow multimedia        # Entweder nur das Package "multimedia" bereitstellen ...
stow *                 # ... oder alle Packages bereitstellen.

Wenn die Beispielpackages bereitgestellt werden, ergibt sich folgende Struktur.

~
├── .config
│   ├── mpv -> ../.config/dotfiles/multimedia/dot-config/mpv
│   ├── yt-dlp -> ../.config/dotfiles/multimedia/dot-config/yt-dlp
│   └── alacritty -> ../.config/dotfiles/terminal/dot-config/alacritty
└── .zshrc -> .config/dotfiles/terminal/dot-zshrc

Sofern im Target Directory bereits Dateien mit Namen existieren, die durch stow angelegt werden würden, kommt es zu einer entsprechenden Fehlermeldung, und der Vorgang wird abgebrochen.

Will man Packages nicht mehr bereitstellen, muss man sie löschen, dadurch werden die angelegten Symlinks im Target Directory wieder entfernt. Die Packages selbst bleiben dabei inklusive ihres Installation Image erhalten.

stow --delete terminal

Dies löscht beispielsweise das terminal-Package, womit die zsh und Alacritty wieder ihre Standardkonfiguration verwenden.

Die Verzeichnisse „sauber halten“

Es werden standardmäßig durch GNU Stow keine bestehenden Dateien gelöscht, oder das Stow Directory verändert. Wenn man sich aber sicher ist, dass die bestehende Datei aktueller ist, als die aus dem Package kann man GNU Stow mittels --adopt anweisen, die bestehende Datei zu übernehmen und die Datei aus dem Package zu überschreiben, dies ist nur durch stow unwiderruflich und muss im Zweifelsfall durch Git oder ein Backup wiederhergestellt werden.

Wenn man ein Package umbenannt hat, kann man mittels stow neuerpackagename automatisch die alten Symlinks alle auf den neuen Namen umstellen. Wenn man hingegen Dateien im Installation Image entfernt werden, bleiben die Symlinks bestehen, auch wenn man das Package erneut mittels stow packagename bereitstellt. Um Packages sauber neu auszurollen, und dabei alte Symlinks zu entfernen, muss man stow --restow packagename verwenden.

Das Programm mitgelieferte Programm chkstow macht das Auffinden von ungültigen Symlinks komfortabel und einfach.

chkstow -b -t ~/
Bogus link: /home/user/.config/yt-dlp
Bogus link: /home/user/.config/mpv

In wie weit die Links relevant sind, muss man anhand der Linknamen allerdings selbst erfassen. Das Tool listet alle ungültigen Links auf, ohne zu berücksichtigen, ob sie von GNU Stow erfasst werden, oder nicht.

Versionierung mit Git

Da GNU Stow alle Dateien als normale Dateien verwaltet, kann das komplette Stow Directory über Git verwaltet werden.

Auf dem „Originalsystem“ wird das Git-Repository direkt im Stow Directory erstellt. GNU Stow erkennt Git-bezogene Dateien standardmäßig, und ignoriert sie automatisch.

cd ~/.config/dotfiles
git init
git add .stowrc multimedia/ terminal/
[weitere Git-Befehle um das Repository einzurichten]
git push

Auf dem Zielsystem kann man das Repository klonen und mittels stow die Packages bereitstellen.

mkdir -p .config/dotfiles
cd .config/dotfiles
git clone REMOTE-URL .
stow *   # ... oder auch nur einzelne

Je nachdem, wie viele und detaillierte Dotfiles bereitgestellt wurden, ist es eventuell am einfachsten, sich nach dem Bereitstellen einmal ab- und wieder anzumelden. Mindestens sollte man aber die Betroffenen Anwendungen neu starten.

Siehe auch

Weblinks