Note: yay cache .git root cause, find -prune/-delete gotcha, paccache timer
This commit is contained in:
@@ -324,6 +324,115 @@ find . -type f -name "*.tmp" -delete
|
||||
find . -name "*.tmp" -delete
|
||||
```
|
||||
|
||||
### -delete und -prune sind unvereinbar (wichtig!)
|
||||
|
||||
**`-delete` aktiviert automatisch `-depth`.** Bei `-depth` (Tiefensuche) ist `-prune`
|
||||
aber wirkungslos – der Schutz wird also genau dann aufgehoben, wenn man ihn braucht.
|
||||
|
||||
```bash
|
||||
# FALSCH: -prune schützt NICHT, find warnt und führt den Befehl trotzdem aus!
|
||||
find ~/.cache -name .git -prune -o -type f -atime +30 -delete
|
||||
```
|
||||
|
||||
Ausgabe von GNU find:
|
||||
|
||||
```
|
||||
find: Die Option -delete aktiviert -depth automatisch, aber -prune ist wirkungslos,
|
||||
wenn -depth aktiv ist. In diesem Fall muss -depth zusätzlich angegeben werden.
|
||||
```
|
||||
|
||||
Das ist eine **Warnung, kein Fehler** – der Befehl läuft weiter, mit deaktiviertem Schutz.
|
||||
Das hat im April 2026 bei einem AUR-Cache-Cleanup die `.git/HEAD`- und `.git/config`-Dateien
|
||||
von 24 Paketen gelöscht (siehe [[IT-Know-How/Linux/yay Cache reparieren]]).
|
||||
|
||||
**Lösung: `-prune` durch `-not -path` ersetzen.** `-path` funktioniert auch bei `-depth`:
|
||||
|
||||
```bash
|
||||
# RICHTIG: -not -path statt -prune
|
||||
find ~/.cache -type f -atime +30 -not -path '*/.git/*' -delete
|
||||
```
|
||||
|
||||
Verifiziertes Verhalten:
|
||||
|
||||
| Datei | Ergebnis |
|
||||
|-------|----------|
|
||||
| `normal/old.txt` (alt) | gelöscht |
|
||||
| `.git/HEAD` (alt) | **bleibt erhalten** |
|
||||
| `.git/config` (alt) | **bleibt erhalten** |
|
||||
|
||||
> **Merksatz:** `-prune` funktioniert nur bei der *Breitensuche* (Voreinstellung).
|
||||
> Sobald `-depth` im Spiel ist – etwa durch `-delete` oder `-exec` mit `{} +` –
|
||||
> muss der Ausschluss über `-not -path` oder `-not -name` erfolgen.
|
||||
|
||||
### Ausschlusslisten sicher formulieren
|
||||
|
||||
Mehrere Ausschlüsse kombinieren:
|
||||
|
||||
```bash
|
||||
# .git und node_modules ausschließen
|
||||
find . -type f -atime +30 -not -path '*/.git/*' -not -path '*/node_modules/*' -delete
|
||||
|
||||
# statt .git prüfen: nur in echten Cache-Verzeichnissen löschen
|
||||
find ~/.cache -mindepth 2 -type f -atime +30 -not -path '*/.git/*' -delete
|
||||
```
|
||||
|
||||
Immer vorher mit `-print` prüfen, wie viele Dateien betroffen sind:
|
||||
|
||||
```bash
|
||||
find ~/.cache -type f -atime +30 -not -path '*/.git/*' -print | wc -l
|
||||
```
|
||||
|
||||
### noatime: warum -atime auf dem Root-Filesystem täuscht
|
||||
|
||||
Bei einem `noatime`-Mount wird die Zugriffszeit beim **Lesen nicht mehr aktualisiert**.
|
||||
`-atime` misst dann faktisch nur noch das Alter der letzten **Schreiboperation** –
|
||||
also praktisch `mtime`:
|
||||
|
||||
```bash
|
||||
# Mount-Optionen prüfen
|
||||
findmnt -T /home
|
||||
# TARGET SOURCE FSTYPE OPTIONS
|
||||
# / /dev/... ext4 rw,noatime,commit=60
|
||||
|
||||
# Bei noatime ist -atime +30 == "in 30 Tagen nicht mehr geschrieben"
|
||||
```
|
||||
|
||||
Folge: Ein `find -atime +30 -delete` löscht auch Dateien, die **täglich gelesen** werden –
|
||||
sofern sie 30 Tage lang nicht geschrieben wurden. Bei Cache-Bereinigungen ist `-mtime`
|
||||
meist die ehrlichere Wahl, weil Caches ohnehin nur geschrieben, nie gelesen werden.
|
||||
|
||||
`atime` vs. `mtime` im Vergleich:
|
||||
|
||||
| Mount | `-atime +30` bedeutet |
|
||||
|-------|----------------------|
|
||||
| `relatime` (Standard) | wirklich: seit 30 Tagen nicht mehr gelesen |
|
||||
| `noatime` | seit 30 Tagen nicht mehr **geschrieben** |
|
||||
| `strictatime` | wie `relatime`, aber exakter Zeitstempel |
|
||||
|
||||
### Sicheres Aufräumen mit Ausschlussliste
|
||||
|
||||
Kombiniertes Rezept für Cache-Bereinigungen – zuerst prüfen, dann löschen:
|
||||
|
||||
```bash
|
||||
# 1. Was würde gelöscht? (Anzahl + Größe)
|
||||
find ~/.cache -type f -atime +30 -not -path '*/.git/*' -print | wc -l
|
||||
find ~/.cache -type f -atime +30 -not -path '*/.git/*' -printf '%s\n' \
|
||||
| awk '{s+=$1} END {printf "%.2f GB\n", s/1024/1024/1024}'
|
||||
|
||||
# 2. Abhängig vom Ziel:
|
||||
# a) altersbasiert: .git über -not -path ausnehmen
|
||||
find ~/.cache -type f -atime +30 -not -path '*/.git/*' -delete
|
||||
|
||||
# b) nur bestimmte Artefakte: die Endungen begrenzen, .git bleibt außen vor
|
||||
find ~/.cache -type f \( -name '*.pkg.tar.zst' -o -name '*.AppImage' \
|
||||
-o -name '*.tar.gz' \) -not -path '*/.git/*' -delete
|
||||
```
|
||||
|
||||
> **Nicht mit `-prune` löschen:** `-delete` schaltet intern auf `-depth` um, und
|
||||
> `-prune` wird dann wirkungslos. Wer trotzdem `-prune` im selben Befehl nutzt,
|
||||
> verliert den `.git`-Schutz exakt im Moment des Löschens. Ausschlüsse immer über
|
||||
> `-not -path` formulieren.
|
||||
|
||||
### Zu viele Argumente
|
||||
|
||||
```bash
|
||||
@@ -360,3 +469,4 @@ fd -e jpg -x convert {} ... # Mit exec
|
||||
- [[IT-Know-How/Linux/BASH Basics/rsync]] - Dateien synchronisieren
|
||||
- [[IT-Know-How/Linux/BASH Basics/sed]] - Gefundene Dateien bearbeiten
|
||||
- [[IT-Know-How/Linux/BASH Basics/awk]] - Ausgabe von find verarbeiten
|
||||
- [[IT-Know-How/Linux/yay Cache reparieren]] - Realer Anwendungsfall: Cache-Cleanup hat `.git` zerstört
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
# Pacman Paketcache verwalten (paccache)
|
||||
|
||||
Pacman lädt jedes Paket als `.pkg.tar.zst` nach `/var/cache/pacman/pkg` und **löscht es danach
|
||||
nicht mehr**. Der Cache wächst dadurch unbegrenzt – auf diesem System waren es einmal 66 GB,
|
||||
was den Plattenplatz deutlich stärker belegte als der gesamte AUR-Cache (`~/.cache/yay`).
|
||||
|
||||
Mit `paccache` (Paket `pacman-contrib`) lässt sich das steuern.
|
||||
|
||||
---
|
||||
|
||||
## Wo liegt der Cache?
|
||||
|
||||
Standardpfad ist `/var/cache/pacman/pkg`. Wird in `/etc/pacman.conf` kein `CacheDir`
|
||||
gesetzt, gilt dieser Pfad:
|
||||
|
||||
```bash
|
||||
# Konfiguration prüfen
|
||||
grep -E '^CacheDir' /etc/pacman.conf
|
||||
# nicht gesetzt → Standard /var/cache/pacman/pkg
|
||||
|
||||
# Aktuelle Größe (root-owned, daher sudo nötig)
|
||||
sudo du -sh /var/cache/pacman/pkg
|
||||
```
|
||||
|
||||
> **Achtung:** Der Pacman-Cache liegt **nicht** unter `~/.cache/pacman`. Er gehört dem
|
||||
> System und braucht `sudo`. `~/.cache/pacman` existiert auf Arch normalerweise nicht.
|
||||
|
||||
---
|
||||
|
||||
## paccache: Optionen
|
||||
|
||||
*paccache v1.13.1*
|
||||
|
||||
**Operationen** (was passieren soll):
|
||||
|
||||
| Option | Bedeutung |
|
||||
| --- | --- |
|
||||
| `-d, --dryrun` | nur Kandidaten finden, **nichts löschen** |
|
||||
| `-r, --remove` | Kandidaten löschen |
|
||||
| `-m, --move <dir>` | Kandidaten nach `<dir>` **verschieben** statt löschen |
|
||||
|
||||
**Optionen** (wie ausgewählt wird):
|
||||
|
||||
| Option | Bedeutung |
|
||||
| --- | --- |
|
||||
| `-k, --keep <num>` | nur die `<num>` neuesten Versionen pro Paket behalten (**Default: 3**) |
|
||||
| `-u, --uninstalled` | nur Pakete, die derzeit **nicht** installiert sind |
|
||||
| `-c, --cachedir <dir>` | zu durchsuchendes Verzeichnis (Default: aus `/etc/pacman.conf`) |
|
||||
| `--min-atime <zeit>` | Pakete behalten, die jünger als `<zeit>` sind – unabhängig von `-k` |
|
||||
| `--min-mtime <zeit>` | dito, anhand des Änderungsdatums (zuverlässiger, siehe unten) |
|
||||
| `-i, --ignore <pkgs>` | Paketnamen ausschließen (Komma-separiert) |
|
||||
| `-v, --verbose` | ausführlicher, bis `-vvv` |
|
||||
| `-q, --quiet` | Ausgabe reduzieren |
|
||||
| `-f, --force` | entspricht `rm -f` / `mv -f` |
|
||||
| `-z, --null` | null-Trennzeichen in der Ausgabe (nur mit `-v`/`-vv`) |
|
||||
| `--nocolor` | keine Farbformatierung |
|
||||
|
||||
> **Achtung, Default:** Ohne `-k` behält `paccache` **3** Versionen pro Paket. Wer
|
||||
> gezielt reduzieren will, muss `-k` explizit setzen.
|
||||
|
||||
Die beiden wichtigsten Aufrufe:
|
||||
|
||||
```bash
|
||||
# Vorschau: 2 neueste Versionen behalten
|
||||
sudo paccache -rk2 -v
|
||||
|
||||
# Ausführen
|
||||
sudo paccache -rk2
|
||||
```
|
||||
|
||||
### Sicherster Testlauf erst verschieben, dann löschen
|
||||
|
||||
Statt direkt zu löschen kann man Kandidaten in ein Sammelverzeichnis verschieben und
|
||||
erst nach Prüfung endgültig entfernen:
|
||||
|
||||
```bash
|
||||
sudo paccache -m /tmp/pacman-cache-backup -rk2
|
||||
du -sh /tmp/pacman-cache-backup
|
||||
# nach Kontrolle:
|
||||
rm -rf /tmp/pacman-cache-backup
|
||||
```
|
||||
|
||||
### `--min-atime` vs. `--min-mtime`
|
||||
|
||||
Diese Optionen durchbrechen das `-k`-Limit: alles, was jung genug ist, bleibt erhalten.
|
||||
Auf einem **`noatime`**-Mount ist `--min-atime` jedoch unzuverlässig, weil Lesezugriffe
|
||||
die Zugriffszeit nicht mehr aktualisieren – dort misst atime faktisch nur den letzten
|
||||
Schreibzugriff. In dem Fall `--min-mtime` verwenden. Siehe
|
||||
[[IT-Know-How/Linux/BASH Basics/find]].
|
||||
|
||||
### Gemessene Einsparung (System dieses Nutzers, 66 GB Cache)
|
||||
|
||||
| Aufruf | Kandidaten | Freier Speicher |
|
||||
| --- | --- | --- |
|
||||
| `paccache -rk2` (2 Versionen behalten) | 4332 | **40,3 GiB** |
|
||||
| `paccache -ruk0` (nur installierte behalten) | 99 | 12,8 GiB |
|
||||
| `paccache -rk0` (nichts behalten) | 7153 | 65,7 GiB |
|
||||
|
||||
**Empfehlung: `-rk2`.** Es erhält zwei Versionen pro Paket und damit die Möglichkeit,
|
||||
ein Update zurückzunehmen. `-rk0` ist maximal gründlich, lässt aber kein Downgrade zu –
|
||||
bei einem defekten Update dann nur noch der Weg über das Archiv.
|
||||
|
||||
> `-duk0` entfernt ausschließlich Pakete, die gar nicht mehr installiert sind – z. B.
|
||||
> Rückstände nach `pacman -R`. Das ist die unkritischste Variante.
|
||||
|
||||
### Downgrade statt löschen
|
||||
|
||||
Solange die `.pkg.tar.zst` im Cache liegt, funktioniert ein Downgrade direkt:
|
||||
|
||||
```bash
|
||||
sudo pacman -U /var/cache/pacman/pkg/paket-1.0.0-1-x86_64.pkg.tar.zst
|
||||
```
|
||||
|
||||
Genau deshalb ist `-k 2` sinnvoller als `-k 0`.
|
||||
|
||||
---
|
||||
|
||||
## Automatisch aufräumen: paccache.timer
|
||||
|
||||
`paccache` bringt bereits einen **Systemd-Timer** mit, der auf diesem System
|
||||
vorinstalliert, aber **deaktiviert** ist:
|
||||
|
||||
```bash
|
||||
# Status prüfen
|
||||
systemctl is-enabled paccache.timer # → disabled
|
||||
systemctl list-timers paccache.timer
|
||||
```
|
||||
|
||||
Einrichtung:
|
||||
|
||||
```bash
|
||||
# 1. Timer aktivieren (läuft dann wöchentlich)
|
||||
sudo systemctl enable --now paccache.timer
|
||||
|
||||
# 2. Verhalten festlegen: 2 Versionen behalten
|
||||
sudo sed -i 's/^PACCACHE_ARGS=.*/PACCACHE_ARGS="-rk2"/' /etc/conf.d/pacman-contrib
|
||||
|
||||
# 3. Einmalig sofort ausführen
|
||||
sudo systemctl start paccache.service
|
||||
|
||||
# 4. Nächsten Laufzeitpunkt ansehen
|
||||
systemctl list-timers paccache.timer
|
||||
```
|
||||
|
||||
Die Argumente kommen aus der Environment-Datei `/etc/conf.d/pacman-contrib`:
|
||||
|
||||
```bash
|
||||
# Standard: leer
|
||||
PACCACHE_ARGS=
|
||||
```
|
||||
|
||||
Wird sie nicht gesetzt, verwendet der Service nur `paccache -r` (Standardverhalten des
|
||||
Tools). Deshalb lohnt sich das Setzen auf `-rk2`.
|
||||
|
||||
Der Service ist bereits sinnvoll vorkonfiguriert – `Type=oneshot`, `Nice=19`,
|
||||
`CPUSchedulingPolicy=idle` sowie diverse Härtungsoptionen (`ProtectSystem=full`,
|
||||
`ProtectHome=yes`, `NoNewPrivileges=yes`, …). Die Cache-Bereinigung läuft also mit
|
||||
niedrigster Priorität und blockiert keine interaktive Arbeit.
|
||||
|
||||
`Persistent=true` ist im Timer gesetzt: War der Rechner ausgeschaltet, wird die
|
||||
aufgeholte Ausführung beim nächsten Start nachgeholt.
|
||||
|
||||
### Rhythmus ändern
|
||||
|
||||
Standard ist `OnCalendar=weekly`. Für einen selteneren Durchlauf einen Drop-in anlegen:
|
||||
|
||||
```bash
|
||||
sudo systemctl edit paccache.timer
|
||||
```
|
||||
|
||||
```ini
|
||||
[Timer]
|
||||
OnCalendar=
|
||||
OnCalendar=monthly
|
||||
```
|
||||
|
||||
Die **leere** `OnCalendar=` ist wichtig: sie setzt die vorhandene Liste zurück, sonst
|
||||
hätte das System beide Zeitpläne (weekly *und* monthly) parallel.
|
||||
|
||||
Danach:
|
||||
|
||||
```bash
|
||||
systemctl cat paccache.timer # Drop-in prüfen
|
||||
systemctl list-timers paccache.timer
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Warum kein Cron?
|
||||
|
||||
Für diese Aufgabe ist ein Cronjob die schlechtere Wahl:
|
||||
|
||||
1. **Root ohne interaktive Passwortabfrage.** Der Job bräuchte `sudo` im Befehl.
|
||||
Ein `sudo`-Prompt in einer Cron-Umgebung schlägt still fehl – der Job sieht aus, als
|
||||
liefe er, passiert aber nichts. Bei einem User-Cron zusätzlich: Cron läuft ohne
|
||||
volles Terminal, `sudo` kann die Passwortabfrage oft nicht darstellen.
|
||||
2. **Die systemd-Unit existiert bereits.** Sie ist sandboxed, priorisiert und
|
||||
`Persistent`. Das in Cron nachzubauen hieße, es schlechter zu machen.
|
||||
3. **Ausgabe geht verloren.** Bei `journalctl -u paccache.service` ist nachvollziehbar,
|
||||
was gelöscht wurde – bei Cron nur in Logdateien.
|
||||
|
||||
Als Faustregel: **Was eine Aufgabe als Root und/oder regelmäßig braucht → systemd-Timer.
|
||||
Was als normaler User und unregelmäßig läuft → Cron oder `systemd-run --user`.**
|
||||
|
||||
Für den AUR-Cache ist Automation ohnehin unnötig: `yay -Sc` räumt ihn auf, und er
|
||||
belegt nur noch ~100 MB. Siehe [[IT-Know-How/Linux/yay Cache reparieren]].
|
||||
|
||||
---
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [[IT-Know-How/Linux/yay Cache reparieren]] - AUR-Cache, `.git`-Korruption durch Cleanup
|
||||
- [[IT-Know-How/Linux/Paketinstallation in Linux-Distributionen]] - pacman/yay Grundbefehle
|
||||
- [[IT-Know-How/Linux/BASH Basics/find]] - sichere `-delete`-Kommandos für Cache-Aufräumen
|
||||
@@ -22,11 +22,50 @@ Fehlermeldung (Beispiel `supersonic-desktop`, August 2026):
|
||||
## Ursache
|
||||
|
||||
Der lokale Klon des AUR-Repos in yays Cache (`~/.cache/yay/<paket>`) ist **korrupt**.
|
||||
Typisch: der `.git`-Ordner ist unvollständig (z. B. fehlen `HEAD` oder `config`),
|
||||
meist nach einem abgebrochenen Clone/Pull oder einer gestörten Synchronisation.
|
||||
Typisch: der `.git`-Ordner ist unvollständig (z. B. fehlen `HEAD` oder `config`).
|
||||
|
||||
Das AUR-Paket selbst ist in Ordnung – nur die lokale Kopie ist kaputt.
|
||||
|
||||
### Mögliche Auslöser
|
||||
|
||||
1. Abgebrochener Clone/Pull oder eine gestörte Synchronisation
|
||||
2. **Aggressive Cache-Bereinigung** (realer Fall, September 2026) – siehe unten
|
||||
|
||||
### Ursache 2: Cache-Cleanup hat die `.git`-Metadaten gelöscht
|
||||
|
||||
Der AUR-Cache unter `~/.cache/yay` ist selbst nur ein Build-Cache. Wird er per
|
||||
`find` mit Alterskriterium aufgeräumt, greift die Suche **auch in die `.git`-Ordner**
|
||||
hinein und löscht dort genau die Dateien, die Git zum Erkennen eines Repos braucht:
|
||||
|
||||
```bash
|
||||
# 2026-04-24 ausgeführt – hat 24 AUR-Klone gleichzeitig zerstört
|
||||
find ~/.cache -type f -atime +30 -delete
|
||||
```
|
||||
|
||||
Ergebnis pro betroffenem Paket:
|
||||
|
||||
| Datei | Status | Warum |
|
||||
|-------|--------|-------|
|
||||
| `.git/HEAD` | **gelöscht** | seit dem Clone (13.02.) nicht mehr geschrieben → >30 Tage alt |
|
||||
| `.git/config` | **gelöscht** | dito |
|
||||
| `.git/description` | **gelöscht** | dito |
|
||||
| `.git/hooks/*.sample` | gelöscht | dito |
|
||||
| `.git/info/exclude` | gelöscht | dito |
|
||||
| `.git/logs/**` (Reflog) | gelöscht | dito |
|
||||
| `.git/index` | überlebt | beim Build am 19.04. neu geschrieben → <30 Tage |
|
||||
| `.git/ORIG_HEAD` | überlebt | dito |
|
||||
| `.git/objects/**` | überlebt | nur gelesen, nicht geschrieben |
|
||||
| `.git/refs/**` | überlebt | dito |
|
||||
|
||||
**Warum genau `HEAD` und `config` fehlen:** Git erkennt ein Repository anhand von
|
||||
`HEAD` + `objects` + `refs`. Fehlt `HEAD`, gilt der Ordner nicht mehr als Repository –
|
||||
daher die Fehlermeldung, obwohl der Ordner und die Objekte noch da sind.
|
||||
|
||||
Der entscheidende Punkt: Auf einem **`noatime`-Mount** aktualisiert Lesen die Zugriffszeit
|
||||
nicht mehr. `-atime +30` bedeutet dort also *"seit 30 Tagen nicht mehr **geschrieben**"* –
|
||||
und nicht *"seit 30 Tagen nicht benutzt"*. Genau deshalb wurden auch Klone gelöscht,
|
||||
die täglich gelesen wurden. Details: [[IT-Know-How/Linux/BASH Basics/find]].
|
||||
|
||||
---
|
||||
|
||||
## Diagnose
|
||||
@@ -39,6 +78,47 @@ git -C ~/.cache/yay/<paket> status
|
||||
|
||||
Kommt dieselbe Meldung („Kein Git-Repository"), obwohl der Ordner existiert → Cache-Klon löschen.
|
||||
|
||||
Schnellcheck des `.git`-Inhalts:
|
||||
|
||||
```bash
|
||||
ls ~/.cache/yay/<paket>/.git
|
||||
# Erwartet: HEAD config objects refs index ...
|
||||
```
|
||||
|
||||
### Warum meldet `yay -Ss` keinen Fehler?
|
||||
|
||||
`yay -Ss` fragt die AUR-RPC-Schnittstelle per HTTP ab und braucht den lokalen Klon
|
||||
dafür nicht. Erst `yay -S`/`-Syu` führt ein `git pull` im Cache-Ordner aus – daher
|
||||
funktioniert die *Suche*, während das *Installieren/Updaten* fehlschlägt.
|
||||
|
||||
### Forensik: eigene Hausarbeit prüfen
|
||||
|
||||
Falls unklar ist, **wann** und **wodurch** die Klons zerstört wurden, hilft der
|
||||
Dateisystem-Zeitstempel. Alle betroffenen `.git`-Ordner tragen denselben mtime,
|
||||
weil ein einziger Prozess sie in einem Durchlauf angefasst hat:
|
||||
|
||||
```bash
|
||||
# Alle zerstörten Klons finden
|
||||
find ~/.cache/yay -mindepth 2 -maxdepth 2 -type d -name .git \
|
||||
! -exec test -f '{}/HEAD' \; -printf '%h\n'
|
||||
|
||||
# mtime vergleichen (hier: alle exakt 2026-04-24 12:29:16)
|
||||
find ~/.cache/yay -mindepth 2 -maxdepth 2 -type d -name .git \
|
||||
-printf '%T+ %h\n' | sort
|
||||
```
|
||||
|
||||
Der Zeitstempel lässt sich gegen die Shell-History abgleichen:
|
||||
|
||||
```bash
|
||||
# fish: Epoch-Sekunden der History-Einträge umrechnen
|
||||
grep -n 'atime' ~/.local/share/fish/fish_history
|
||||
date -d @1777026555 # → 2026-04-24 12:29:15 CEST
|
||||
```
|
||||
|
||||
Ein im Nanosekunden-Bereich aufeinanderfolgender Versatz zwischen den Verzeichnissen
|
||||
(`.4006957730`, `.4016957760`, …) bestätigt einen einzelnen `find`-Durchlauf statt
|
||||
manueller Eingriffe.
|
||||
|
||||
---
|
||||
|
||||
## Lösung
|
||||
@@ -54,6 +134,27 @@ yay klont das PKGBUILD-Repo beim nächsten Lauf frisch – danach funktioniert d
|
||||
|
||||
---
|
||||
|
||||
## Alle betroffenen Pakete auf einmal reparieren
|
||||
|
||||
Sind mehrere Klons betroffen (z. B. nach einem pauschalen Cleanup), alle auf einmal
|
||||
finden und entfernen. `-printf '%h'` liefert den übergeordneten Paketordner, `%h\0`
|
||||
plus `xargs -0` ist gegen Leerzeichen in Pfaden sicher:
|
||||
|
||||
```bash
|
||||
# 1. Erst ansehen – nur anzeigen, nicht löschen
|
||||
find ~/.cache/yay -mindepth 2 -maxdepth 2 -type d -name .git \
|
||||
! -exec test -f '{}/HEAD' \; -printf '%h\n'
|
||||
|
||||
# 2. Dann entfernen
|
||||
find ~/.cache/yay -mindepth 2 -maxdepth 2 -type d -name .git \
|
||||
! -exec test -f '{}/HEAD' \; -printf '%h\0' | xargs -0 rm -rf
|
||||
```
|
||||
|
||||
Betroffen sind nur unbrauchbare Klone. yay klont sie beim nächsten Build neu;
|
||||
installierte Pakete bleiben unberührt.
|
||||
|
||||
---
|
||||
|
||||
## Allgemein: yay-Cache aufräumen
|
||||
|
||||
| Vorgehen | Befehl | Folge |
|
||||
@@ -64,3 +165,68 @@ yay klont das PKGBUILD-Repo beim nächsten Lauf frisch – danach funktioniert d
|
||||
|
||||
**Faustregel:** Immer erst den einzelnen Paketordner löschen. Den kompletten Cache nur leeren,
|
||||
wenn mehrere Pakete betroffen sind – er enthält nichts Kritisches, kostet aber Rebuild-Zeit.
|
||||
|
||||
| Befehl | Wirkung |
|
||||
| --- | --- |
|
||||
| `yay -Sc` | Entfernt Build-Artefakte (untracked/gitignored) aus den Paketordnern, fragt zusätzlich nach dem Pacman-Cache |
|
||||
| `yay -Scc` | Wie `-Sc`, leert aber **alle** AUR-Build-Ordner vollständig (inkl. `.git`) |
|
||||
| `paccache -rk2` | Pacman-Cache aufräumen, 2 Versionen behalten – siehe [[IT-Know-How/Linux/Pacman Paketcache verwalten]] |
|
||||
|
||||
> **Vorsicht bei `yay -Scc`:** Nimmt auch die `.git`-Ordner mit, d. h. alles wird beim
|
||||
> nächsten `-Syu` neu geklont. Für einen Cache dieser Größe unkritisch, aber langsam bei
|
||||
> vielen AUR-Paketen mit langen Buildzeiten.
|
||||
|
||||
### Was der AUR-Cache tatsächlich belegt
|
||||
|
||||
Ein Build hinterlässt je Paket teure Dateien im Cache-Ordner: das heruntergeladene
|
||||
Quell-Archiv bzw. AppImage und das fertige `.pkg.tar.zst`. Im September 2026 belegten
|
||||
vier alte LM-Studio-Versionen allein 7,1 GB (4 × AppImage + 4 × fertiges Paket).
|
||||
|
||||
Diese Artefakte sind exakt das, was die `.gitignore` der AUR-Repos ausschließt
|
||||
(`*.AppImage`, `*.pkg.tar.zst`, `src/`, `pkg/`, `*.tar.gz`, …) – deshalb entfernt
|
||||
`yay -Sc` / `git clean -xdf` sie zuverlässig.
|
||||
|
||||
Gezielt aufräumen – Prüfen und Löschen getrennt, weil `-delete` und `-prune` nicht
|
||||
kombinierbar sind:
|
||||
|
||||
```bash
|
||||
# 1. Prüfen: Anzahl und Größe (darf -prune verwenden, da nur -print)
|
||||
find ~/.cache/yay -name .git -prune -o -type f \
|
||||
\( -name '*.pkg.tar.zst' -o -name '*.AppImage' -o -name '*.deb' \
|
||||
-o -name '*.tar.gz' -o -name '*.tar.xz' \) -printf '%s\n' \
|
||||
| awk '{s+=$1;n++} END {printf "%d Dateien, %.2f GB\n", n, s/1024/1024/1024}'
|
||||
|
||||
# 2. Löschen: OHNE -prune, stattdessen .git über -not -path ausnehmen
|
||||
find ~/.cache/yay -type f \
|
||||
\( -name '*.pkg.tar.zst' -o -name '*.AppImage' -o -name '*.deb' \
|
||||
-o -name '*.tar.gz' -o -name '*.tar.xz' \) \
|
||||
-not -path '*/.git/*' -delete
|
||||
```
|
||||
|
||||
> **Warum zwei Befehle?** `-delete` schaltet intern auf `-depth` um, und `-prune`
|
||||
> ist dann wirkungslos – der `.git`-Schutz fällt weg. Zum Zählen/Lösen ist `-prune`
|
||||
> mit `-print` ok, beim Löschen aber durch `-not -path '*/.git/*'` ersetzen. Details:
|
||||
> [[IT-Know-How/Linux/BASH Basics/find]].
|
||||
|
||||
---
|
||||
|
||||
## Prävention
|
||||
|
||||
Damit das nicht noch einmal passiert:
|
||||
|
||||
1. **Kein `-delete` über `~/.cache` ohne `.git`-Ausschluss.** Immer `-not -path '*/.git/*'`
|
||||
verwenden, niemals `-prune` (das ist unter `-delete` wirkungslos).
|
||||
2. **Besser gar nicht pauschal aufräumen.** `~/.cache/yay` ist ein reiner Build-Cache und
|
||||
enthält nichts Unwiederbringliches – `yay -Sc` ist der vorgesehene Weg.
|
||||
3. **Auf `noatime`-Mounts `-atime` nicht als „letzte Nutzung" lesen.** Vorher prüfen:
|
||||
`findmnt -T /home`
|
||||
4. **Regelmäßig `paccache -rk2`** – der Pacman-Cache wächst unbegrenzt und war mit
|
||||
66 GB der eigentliche Plattenfresser (siehe [[IT-Know-How/Linux/Pacman Paketcache verwalten]]).
|
||||
|
||||
---
|
||||
|
||||
## Siehe auch
|
||||
|
||||
- [[IT-Know-How/Linux/BASH Basics/find]] - `-delete`/`-prune`-Konflikt und `noatime`
|
||||
- [[IT-Know-How/Linux/Pacman Paketcache verwalten]] - `paccache` und der Pacman-Cache
|
||||
- [[IT-Know-How/Linux/Paketinstallation in Linux-Distributionen]] - pacman/yay Grundbefehle
|
||||
|
||||
Reference in New Issue
Block a user