Handbuch
Alles, was das Kommandozeilenwerkzeug kann, in der Reihenfolge, in der Sie es wahrscheinlich brauchen. --help bei jedem Befehl gibt dasselbe ohne Browser aus.
Erster Scan
Ein Scan läuft einen Ordner durch und gibt aus, was er gefunden hat. Nichts wird gespeichert, nichts verändert.
$ spacetrace scan ~/projects
scanned 84,213 entries in 1.9s
total 12.4 GiB logical · 12.7 GiB on disk
3 paths could not be readUnlesbare Pfade werden gezählt und stichprobenartig gezeigt, statt den Durchlauf abzubrechen. Unter macOS braucht der Weg aus Ihrem persönlichen Ordner heraus Full Disk Access für das Terminal; ohne das läuft der Scan trotzdem durch und sagt, was er nicht gesehen hat.
Schneller und enger machen
spacetrace scan / -x spacetrace scan ~/code --exclude node_modules --exclude .git spacetrace scan /var --depth 3 spacetrace scan /srv --no-dedupe
--exclude nimmt einen Verzeichnisnamen, keinen Pfad, und lässt sich wiederholen. In ausgeschlossene Ordner wird nie hineingegangen: node_modules auf einer Entwicklungsmaschine auszuschließen ist meist der Unterschied zwischen zwei und dreißig Sekunden.
Momentaufnahmen und Vergleich
Das ist der Teil, den andere Analysatoren nicht haben. Einen Scan speichern, später noch einen, und fragen, was sich dazwischen verändert hat.
$ spacetrace scan /srv --save --label weekly saved snapshot #1 $ spacetrace scans ID WHEN HOST ROOT LABEL TOTAL 2 2026-09-06 19:40 srv-01 /srv 76.3 MiB 1 2026-09-06 17:23 srv-01 /srv weekly 23.8 MiB
Dann vergleichen. Ohne Argumente nimmt es die letzten beiden.
$ spacetrace diff --path /srv
#1 2026-09-06 17:23 [weekly] → #2 2026-09-06 19:40
total 23.8 MiB → 76.3 MiB (+52.5 MiB)
CHANGE STATUS NEW PATH
+40.1 MiB grew 42.9 MiB app/logs/
+14.3 MiB grew 25.7 MiB backups/
-1.9 MiB removed 0 B uploads/Ein Ordner, dessen Wachstum vollständig von einem einzigen Kind kommt, sagt Ihnen nichts Neues und wird deshalb übersprungen. Der Bericht nennt die erste Ebene, auf der sich die Veränderung wirklich verteilt — den Verursacher, nicht seine Vorfahren.
Gegen die Platte, wie sie jetzt ist
Sie brauchen keine zwei Momentaufnahmen. Vergleichen Sie die neueste mit einem laufenden Scan:
spacetrace diff --since-last /srvAuswählen, was erscheint
spacetrace diff --path /srv --min 10M spacetrace diff --path /srv --files spacetrace diff 3 7
Die Datenbank nicht unendlich wachsen lassen
spacetrace prune --path /srv --keep 30 spacetrace rm 4
Einen Scan durchsehen
ls listet Ordner nach Größe — aus einem laufenden Scan oder aus einer gespeicherten Momentaufnahme.
spacetrace ls /var/lib --top 20 spacetrace ls --scan 3 --subpath docker/overlay2
Um eine Momentaufnahme an etwas anderes zu geben, schreibt export das Format von ncdu:
spacetrace export --scan 3 --out scan.json && ncdu -f scan.jsonJeder Befehl nimmt außerdem --json, und das ist der unterstützte Weg, darauf zu skripten. Die menschenlesbaren Spalten dürfen sich ändern, die Form des JSON nicht.
Der Agent auf einem Server
spacetrace-agent ist derselbe Code als Dienst: er scannt die konfigurierten Wurzeln nach Zeitplan, bewahrt die Momentaufnahmen auf und antwortet über HTTP. Eine statische Binärdatei — und er liest nur; es gibt in ihm keinen Codeweg, der außerhalb seiner eigenen Momentaufnahmen-Datenbank etwas löscht.
Konfiguration und Token schreiben
spacetrace-agent init > /etc/spacetrace/agent.tomlhead -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n' > /etc/spacetrace/token && chmod 600 /etc/spacetrace/tokenserve startet ohne Token nicht. Ein Agent ohne Authentifizierung übergibt sein gesamtes Dateisystem-Inventar an jeden, der den Port erreicht.
Sagen, was wann gescannt wird
db = "/var/lib/spacetrace/snapshots.sqlite" utc_offset_minutes = 0 [server] listen = "127.0.0.1:7878" token_file = "/etc/spacetrace/token" [[roots]] path = "/var" schedule = "0 3 * * *" label = "nightly" exclude = ["node_modules", ".git"] one_file_system = true keep = 14
Fünf Cron-Felder, mit *, a-b, */n und Listen. Keine Sekunden, kein @daily. Unbekannte Konfigurationsschlüssel werden beim Start abgelehnt, denn ein Tippfehler, der auf einer unbeobachteten Maschine stillschweigend nichts tut, ist schlimmer als eine Startverweigerung.
Vor dem Start prüfen
$ spacetrace-agent --config /etc/spacetrace/agent.toml check config ok database /var/lib/spacetrace/snapshots.sqlite host nas listen 127.0.0.1:7878 token configured ad-hoc scans refused ROOT SCHEDULE NEXT RUN /var 0 3 * * * 2026-09-09 03:00 Times are UTC.Ein Zeitplan, der nie auslösen kann, meldet never statt still zu scheitern.
Starten
systemctl enable --now spacetrace-agentDie mitgelieferte systemd-Unit führt den Agenten als eigenen unprivilegierten Benutzer mit ProtectSystem=strict aus, mit Nice=10 und Idle-E/A-Priorität. Ein Scan darf nie dem in den Weg kommen, wofür die Maschine eigentlich da ist.
In Docker den Host schreibgeschützt einhängen und den scannen:
docker run -d --name spacetrace \ -v /:/host:ro \ -v spacetrace-data:/var/lib/spacetrace \ -v /etc/spacetrace:/etc/spacetrace:ro \ -p 7878:7878 \ ghcr.io/unalcakir28/spacetrace
Bevor Sie ihn nach außen geben
- Er lauscht standardmäßig auf Loopback. Ein Dateisystem-Inventar in ein Netz zu stellen, muss eine bewusste Änderung sein.
- Im Agenten gibt es kein TLS. Setzen Sie einen Reverse Proxy davor.
- Das Token wird ohne vorzeitigen Abbruch verglichen: ein falsches Token braucht gleich lange zur Ablehnung, egal wie viel davon richtig war.
- /health braucht kein Token, damit ein Container-Healthcheck funktioniert, und gibt nur Status und Version zurück — keinen Hostnamen, keine Wurzeln.
- Scans auf Zuruf sind aus. Eingeschaltet kann jeder mit dem Token jedes Verzeichnis auflisten, das der Benutzer des Agenten lesen darf.
Eine andere Maschine lesen
Jeder lesende Befehl nimmt --remote. Es ist nichts Neues zu lernen: dieselben Unterbefehle, nur woanders hin gerichtet.
export SPACETRACE_TOKEN=… spacetrace --remote https://nas.example.com scans spacetrace --remote https://nas.example.com diff --path /var spacetrace --remote https://nas.example.com ls --top 20 spacetrace --remote https://nas.example.com pull --root /var
Speichern Sie ein Ziel, damit URL und Token nicht mehr getippt werden müssen — in ~/.config/spacetrace/remotes.toml:
[remotes.nas] url = "https://nas.example.com" token = "…"
Was über die Leitung kommt, ist dieselbe eigenständige SQLite-Datei, die der Agent aufbewahrt: auflisten, durchsehen und vergleichen läuft mit genau demselben Code wie bei einer lokalen. Sie können das Werkzeug auch ganz weglassen und trotzdem eine Datei bekommen, die Sie öffnen können:
curl -H "Authorization: Bearer $SPACETRACE_TOKEN" \ https://nas.example.com/scans/7/download -o snap.sqlite spacetrace --db snap.sqlite scans
scan, prune und rm verweigern sich mit --remote: sie arbeiten auf lokalem Zustand, und der Agent löscht nichts.
Welche Größe, und warum
Jeder Eintrag trägt zwei Zahlen, und keine ist eine Schätzung der anderen.
| Maß | Was es ist | Stimmt überein mit |
|---|---|---|
| logisch | Die Länge, die jede Datei angibt | du -sb |
| auf der Platte | Tatsächlich belegte Blöcke, Verzeichnisblöcke inbegriffen | du -s --block-size=1 |
| Kapazität | Freier Platz von gesamt, auf dem gescannten Dateisystem | der Avail-Spalte von df, exakt |
Sie weichen in beide Richtungen ab, und beide sind richtig. Eine Ein-Byte-Datei belegt einen ganzen Block, ist auf der Platte also größer als ihre Länge. Eine Sparse-Datei gibt eine Länge an, die sie nie belegt hat: ein Platten-Image kann ein Terabyte behaupten und neunzehn Gigabyte belegen.
Sparse-Dateien sind der Grund, warum die App auf der Platte voreinstellt. Images virtueller Maschinen, Datenbankdateien und Core-Dumps gehören auf jeder echten Platte zu den größten Einträgen — das logische Maß irrt sich also genau bei den Einträgen am stärksten, die am meisten zählen. Die Kommandozeile stellt logisch voreingestellt, und beide sagen, welches sie zeigen.
Die Kapazität wird als frei von gesamt gemeldet, nie als „% belegt“. Auf einem Dateisystem, dessen Platz zwischen Volumes geteilt wird — APFS-Container, btrfs-Subvolumes, Thin-LVM — würde eine Belegt-Zahl die Geschwister mitzählen und df für denselben Mountpunkt widersprechen.
Hardlinks werden standardmäßig einmal gezählt; die zweite Kopie erscheint im Baum mit einem Beitrag von null Byte. Symlinks werden nie verfolgt und zählen mit ihrer eigenen Größe.
Befehlsübersicht
- spacetrace scan PATH
- --save, --label
- spacetrace scans
- —
- spacetrace diff
- --path, --since-last, ID ID
- spacetrace ls PATH
- --top, --scan, --subpath
- spacetrace export
- --scan, --out
- spacetrace pull --root PATH
- --remote
- spacetrace prune / rm
- --keep, ID
- spacetrace-agent init
- —
- spacetrace-agent check
- —
- spacetrace-agent serve
- —
- spacetrace-agent push URL
- --root, --token
Optionen, die bei den meisten Befehlen gelten
- --exclude NAME
- -x, --one-file-system
- --depth N
- --min SIZE
- --files
- --no-dedupe
- --json
- --db PATH
- --remote NAME|URL
Wo was liegt
| Plattform | Momentaufnahmen-Datenbank |
|---|---|
| macOS | ~/Library/Application Support/spacetrace/ |
| Linux | $XDG_DATA_HOME/spacetrace/ |
| Überall | SPACETRACE_HOME überschreibt das; --db überschreibt es für einen einzelnen Befehl |
Die Desktop-App schreibt in dieselbe Datenbank: eine in der App gespeicherte Momentaufnahme erscheint in spacetrace scans — und umgekehrt.
Bekannte Grenzen
Veröffentlicht, statt entdeckt zu werden. Wenn Sie auf eine davon stoßen, ist es bekannte Schuld, keine Überraschung.
- Unter Windows entspricht die Größe auf der Platte der logischen Größe, und die Hardlink-Deduplizierung ist aus. Echte Zahlen brauchen GetFileInformationByHandleEx und FileIdInfo.
- APFS-Klone werden nicht dedupliziert, und auf btrfs oder ZFS führen Reflinks und Kompression dazu, dass ein Baumdurchlauf die echte Nutzung nicht melden kann. Kein Baumdurchlauf kann das; die Zahlen sind die der Dateien selbst.
- Ein Scan hält den ganzen Baum im Speicher. Das Speicherprofil jenseits von zehn Millionen Dateien ist nicht gemessen.
- Der Agent hat kein TLS und keine Ratenbegrenzung. Nutzen Sie einen Reverse Proxy; das Token ist ohnehin Pflicht.
- Der Scheduler hat keine Zeitzonendatenbank — UTC plus ein fester Offset, Sommerzeitwechsel bleiben also Ihre Sache.