iX 8/2024
S. 44
Titel
Administration

Shelltools in Rust – was zum Teufel?

Etablierte Kommandozeilenwerkzeuge für Linux und Unix wie ls oder grep existieren als Nachbau neuerdings auch in Rust, und mancher verbindet mit der Reimplementierung große Hoffnung in Sachen Komfort, Performance und Robustheit. Was motiviert die Macher dieser Werkzeuge, wie praktisch sind sie im Alltag und lohnt sich für passionierte Admins ein Blick über den Tellerrand?

Von Martin Gerhard Loschwitz

Wenn Filme- und Serienmacher Hacker bei der Arbeit zeigen, muss dafür üblicherweise der Quelltext von Programmen oder die Kommandozeile herhalten, auf der manchmal sogar Befehle wie ip mit der korrekten Ausgabe zu sehen sind. Passionierte Systemadministratoren können da nur lachen – denn natürlich wissen sie, dass hier nichts Sinistres vonstattengeht, sondern dass Werkzeuge wie ls, du oder grep einfach Bestandteil der Arbeit sind.

Die meisten Administratoren haben die gängigen Befehle so weit verinnerlicht, dass sie unmittelbar nach dem Öffnen einer Shell oder nach dem Aufbau einer SSH-Verbindung quasiautomatisch ein paar CLI-Befehle absetzen: ls, um zu schauen, welche Dateien lokal vorhanden sind, ps, um zu erfahren, was auf dem System los ist, w, um die gerade eingeloggten Nutzer zu zeigen, und so weiter.

Etwas Seltsames allerdings geht seit einer Weile vor sich im Land der Kommandozeile: Eine kleine Gruppe von Enthusiasten ist dabei, Rust-Versionen der gängigen CLI-Werkzeuge zu bauen und die alteingesessenen Werkzeuge durch diese neuen Versionen zu ersetzen. Modernes Teufelszeug, wirft mancher Administrator da intuitiv ein. Wer dem Thema so begegnet, liefert aber eine zumindest unterkomplexe Analyse der Situation.

Muss man das ernst nehmen?

Was als akademisches Projekt für Rust-Eiferer begonnen haben mag, hat sich nämlich längst zu einer ernst zu nehmenden Bewegung entwickelt, und die Rust-Versionen der CLI-Standardwerkzeuge sind längst mehr als einfache Klone. So verweisen die Entwickler von Tools wie ripgrep statt grep, eza statt ls und procs statt ps beispielsweise darauf, dass Rust als extrem effiziente Programmiersprache gilt, die für den Bau von CLI-Werkzeugen wie geschaffen sei. Gerade wer sich mit grep, sed oder awk schon mal durch größere Datenmengen gewühlt hat, weiß, dass das schnell eine zeitraubende Angelegenheit wird. ripgrep, ruplacer und frawk sollen hier durch deutliche Performancezugewinne punkten.

Obendrein ist Rust für sein robustes Memory Handling bekannt, sodass typischerweise aus mangelhafter Speicherverwaltung resultierende Sicherheitslecks und Stabilitätsprobleme erst gar nicht entstehen können. Zugegeben: Bugs in ls oder ps lassen sich selten ausnutzen, um Systeme zu übernehmen. Unmöglich ist das aber nicht. Bei Rust, so die Rust-Fans, sei die Wahrscheinlichkeit dafür viel geringer.

Grund genug, sich die verfügbaren Rust-Klone bestehender CLI-Werkzeuge einmal genauer anzuschauen und dabei über den Elefanten zu sprechen, der offensichtlich im Raum steht: Versenken die Rust-Fans viel Zeit in ein Hobby, das außerhalb der Rust-Gemeinde niemandem nützt – oder können die in Rust verfassten Alternativen zu klassischen CLI-Werkzeugen einen tatsächlichen Mehrwert gegenüber ihren etablierten Vorfahren bieten?

Quer durchs Gemüsebeet

Um es gleich am Anfang klar zu sagen: Nur die ganz harten Rust-Fans wünschen sich, dass das Gros der Admins seine lieb gewonnenen Shell-Utils wegwirft und ab sofort stattdessen exklusiv mit den jeweiligen Rust-Varianten arbeitet. Das dürfte in den meisten Fällen schon deshalb auch praktisch unmöglich sein, weil es die gängigen CLI-Werkzeuge schon so lange gibt, dass ihre Nutzung wie beschrieben vielen Admins längst in Fleisch und Blut übergegangen ist. Die Muße, sich eine ganze Weile dazu zu zwingen, statt ps lieber procs einzugeben, bis dieses ebenso fast schon unbewusst den Weg durch die Finger auf die Tastatur findet, dürften die wenigsten Admins haben.

Das bedeutet aber nicht, dass die in Rust verfassten Alternativen zu den gängigen CLI-Werkzeugen sich zu bestimmten Einsatzzwecken oder zu besonderen Anlässen nicht hervorragend als Ergänzung zu ihren Gegenstücken in C verwenden ließen. Und eben darauf läuft es in den meisten Fällen auch erst mal hinaus. Aus Sicht interessierter Admins stellt sich damit vor allem die Frage, welche bekannten Tools überhaupt Rust-Alternativen besitzen und was diese leisten. Ein paar Rust-Verfechter haben zu diesem Thema übersichtliche Tabellen zusammengetragen, die einen guten ersten Eindruck der Wahlmöglichkeiten bieten (siehe ix.de/zmcw). Und diese langen Listen machen schnell deutlich: Den Rust-Enthusiasten ist es mit ihrem Anliegen durchaus ernst (siehe auch Tabelle „Rust-Tools und ihre C-Pendants“).

Rust-Tools und ihre C-Pendants
Rust-Tools¹ vergleichbares C-Pendant Beschreibung
bartib timewarrior Zeitmanagmenttool
bat cat² Dateiinhalt anzeigen mit Syntaxhighlighting und anderen Features
bottom top anpassbarer grafischer Prozess- und Systemmonitor
choose cut², awk schneidet Abschnitte aus Textzeilen; schnell, anwenderfreundlich
counts sort² | uniq² -c zählt Zeilen und sortiert sie nach Häufigkeit
delta diff³ diff mit Syntaxhighlighting und Side-by-Side-Ansicht
diskonaut du Navigator durch die Festplattenbelegung mit Aufräumfunktion
dua du² schlankes, benutzerfreundliches du
dust du² benutzerfreundliches du mit Baumansicht
dutree du² benutzerfreundliches du mit Baumansicht und weiteren Features
dysk df² benutzerfreundliche, umfangreiche Anzeige der Festplattenbelegung
erdtree du² umfangreiches du mit Ansicht wie bei ls -l, tree oder du
eza ls² umfangreiche Anzeige des Verzeichnisinhalts
fclones ​– findet und entsorgt doppelte Dateien
fd find⁴ schlankes, benutzerfreundliches Finden von Dateien
frawk awk performante awk-ähnliche Skriptsprache
fselect ​– Find mit SQL-ähnlicher Syntax
grex regexgen (JS) erstellt reguläre Ausdrücke anhand von Beispieleingaben
hck cut², awk, xsv cut mit scharfer Klinge
huniq sort² | uniq² löscht oder meldet mehrfach vorkommende Zeilen aus einer sortierten Datei
hyperfine time umfangreiches und anwenderfreundliches Benchmarkwerkzeug
legdur ​–​ erzeugt Hashes ganzer Verzeichnisinhalte und vergleicht sie mit vorherigen
lsd ls² ls deluxe mit vielen Formatierungsoptionen und Icons
macchina ​​– zeigt Systeminformationen an; übersichtlich, anpassbar
mprocs ​–​ startet parallele Prozesse
natls ls² modernes ls
navi tldr interaktives Spickzetteltool
ouch ​​– Metatool für die gängigen Kompressionstools
pastel ​​– Farbenverwaltung
pdu du² parallelisiertes, benutzerfreundliches du
pipr ​​– Piping-Assistent mit Hilfe- und Ausgabevorschaufenster
please, pleaseedit sudo erweitertes sudo mit Unterstützung regulärer Ausdrücke
procs ps moderner Ersatz für ps, zeigt Prozessinformationen an
pueue ​–​ Manager für long-running Tasks
rargs xargs erweiterte Befehlsausführung
rip rm² rm Improved mit Friedhof und Inspektion
ripgrep (rg) grep, ack rekursives grep mit Ausnahmen
rnr rename Batch-Werkzeug zum sicheren Umbenennen mehrerer Dateien und Verzeichnisse
sad sed moderner Stream-Editor
samply ​​– Prozess- und Thread-Profiler
sd sed benutzerfreundliches sed
skim (sk) fzf Klon des Fuzzy Finder
spacer ​​– fügt Trennbalken in Ausgabeunterbrechungen ein
stringsext strings sucht nach Multi-Byte-codierten Strings in Binaries
systeroid sysctl erweitertes und komfortables Tool zur Konfiguration von Kernelparametern zur Laufzeit
tailspin ​​– Logfile-Highlighter
tealdeer tldr Spickzetteltool
tin-summer (sn) du² benutzerfreundliches du mit Ausnahmedefinition
topgrade ​​– Metapaketmanager
xcp cp² erweitertes, komfortables Kopieren
youki runc Container-Runtime
zet uniq², comm² findet Unterschiede, Dubletten, Teil- und Vereinigungsmengen in Dateien und führt sie zusammen
zoxide cd, z, autojump Verzeichnis wechseln mit Gedächnis
¹ Die Links zu den einzelnen Tools sind unter: ix.de/zmcw zu finden; ² auch als uutils-coreutils; ³ auch als uutils-diffutils; ⁴ auch als uutils-findutils​​

Entsprechend umfangreich ist die Liste der Standardwerkzeuge, die mittlerweile auch in Rust zur Verfügung stehen. Naturgemäß stellt sich den Entwicklern dabei eine Herausforderung: Wie sollen die Werkzeuge heißen? Ein echtes Drop-in Replacement würde einen identischen Namen voraussetzen. Das verbietet sich auf den meisten Systemen aber, weil es ansonsten unvermeidbar zu einem Chaos aus C- und Rust-Werkzeugen käme. Die allermeisten Autoren von Rust-Werkzeugen haben sich also für einen Mittelweg entschieden: Die Werkzeuge selbst heißen zwar anders, beherrschen im Wesentlichen aber dieselben Kommandozeilenparameter wie das jeweilige Ursprungswerkzeug aus der GNU-Kollektion.

Auch das ist an dieser Stelle ja durchaus noch zu beachten: Dass cp, ls und Konsorten nämlich nicht nur in der – unter Linux üblicherweise genutzten – Version des GNU-Projekts zur Verfügung stehen, sondern ihrerseits eigentlich ein Nachbau der jeweiligen BSD-Kommandos sind. Die unterstützten Parameter unterscheiden sich zwischen den BSD-Varianten und den GNU-Versionen dabei heute oft noch im Detail. Wer beispielsweise regelmäßig auf macOS arbeitet und dort das Terminal nutzt, hat die zu Darwin gehörenden Kommandozeilenwerkzeuge vorinstalliert, die von den BSD-Versionen abstammen. Tools wie grep und ps quittieren einen Aufruf, der auf einem Linux-System klappen würde, dann oft bloß mit einer Fehlermeldung.

Damit das Chaos sich nicht in die Rust-Welt fortsetzt, entscheiden sich die meisten Rust-Entwickler zumindest für teilweise Kompatibilität mit den jeweiligen GNU-Werkzeugen. Das bedeutet auch, dass es in Skripten recht einfach ist, von der C-Variante auf die Rust-Variante umzustellen. Denn ein Kommando wie ls -la wird dann einfach zu eza -la, ansonsten ändert sich aber kaum etwas (siehe Abbildung 1). Überhaupt ist eza ein gutes Beispiel dafür, dass sich mit den Rust-Nachbauten der gängigen CLI-Werkzeuge sinnvoll arbeiten lässt.

Auch eza tritt als Alternative zu ls an, kommt aber deutlich bunter daher und versteht sich nicht als echter Ersatz für das ls aus den GNU Coreutils (Abb. 1).
Auch eza tritt als Alternative zu ls an, kommt aber deutlich bunter daher und versteht sich nicht als echter Ersatz für das ls aus den GNU Coreutils (Abb. 1).

Manchen Rust-Entwicklern geht es allerdings um echte Drop-in Replacements. Mit den uutils-coreutils steht deshalb ein in Rust verfasster Werkzeugsatz zur Verfügung, der vollständige CLI-Kompatibilität zu den GNU-Werkzeugen erreichen will und jede Abweichung davon als Bug betrachtet. Hier geht es tatsächlich darum, lieb gewonnene Befehle wie ls durch ein Rust-Pendant zu ersetzen (siehe Abbildung 2 und das Interview auf Seite 58).

uls aus den uutils-coreutils verhält sich exakt so wie GNU ls und ist mit diesem parameter- und mithin auch CLI-kompatibel (Abb. 2).
uls aus den uutils-coreutils verhält sich exakt so wie GNU ls und ist mit diesem parameter- und mithin auch CLI-kompatibel (Abb. 2).

Ruckelige Installation

Bevor sich Werkzeuge wie eza in ihrer ganzen Schönheit verwenden lassen, offenbart ihre Installation allerdings eine der großen Schwachstellen, an denen die Rust-Werkzeuge derzeit leiden. Zumindest jene, die nicht Teil der uutils-coreutils sind. Denn es gibt keine fertige, leicht installierbare Sammlung all jener Werkzeuge, die Standard-CLI-Befehle in Besser mit anderem Namen nachbauen wollen. Jedes Werkzeug kocht stattdessen sein eigenes Süppchen, und will man alle Rust-Substitute für die gängigen CLI-Kommandos zusammentragen, ist das eine aufwendige und zeitraubende Tätigkeit (Eine möglichst vollständige Linksammlung findet sich unter ix.de/zmcw).

Für eza, also den ls-Ersatz in Rust, existiert etwa in Arch Linux eine Integration in Pacman. Für Debian GNU/Linux und die aktuellen Ubuntu-Versionen steht ein PPA-Verzeichnis zur Verfügung. In Gentoo gibt es einen Emerge-Port. Fedora legt eza als RPM-Paket bei, das sich mit dnf einfach installieren lässt. Unter macOS stellt Homebrew eine Variante des Programms bereit.

Mühsame Suche

Wer sich eza so aufs System holt, hat eben nur eza, aber noch kein einziges der vielen anderen für den Alltag nötigen Werkzeuge. Wer procs will, navigiert erst mal zu dessen GitHub-Verzeichnis und sucht die Installationsanweisungen für das eigene Betriebssystem oder die Distribution heraus. Wer das für die zwölf Standardwerkzeuge, die der Nutzer STS10 auf GitHub zusammengetragen hat, praktiziert, hat bald keine Lust mehr.

Erschwerend kommt hinzu, dass es für manche GNU-Werkzeuge nicht nur einen Rust-Ersatz gibt, sondern mehrere konkurrierende. Für diff etwa listet die erwähnte GitHub-Seite delta und difftastic als mögliche Alternativen. Noch bunter wird es bei du: Hier buhlen diskonaut, dua, dust, dutree, erdtree, pdu und tin-summer um die Gunst der Nutzer. Auch für ls steht eine Alternative zu eza in Form von lsd zur Verfügung. Und manche essenziellen Shellwerkzeuge fehlen in der Liste vollständig, etwa ein adäquater, sprich kompatibler Ersatz für awk.

Wieder andere alternative Rust-Implementierungen bekannter Shellutils sind im Netz zwar zu finden, fehlen aber auf der kuratierten Liste. Im Zweifelsfall muss der Admin also mehrere Varianten von Rust-CLI-Alternativen vergleichen und die für ihn beste, am leichtesten zu installierende oder flotteste Alternative herausfinden. Komfortabel ist das nicht, und es verleidet die Vorfreude auf den Einsatz der Rust-Werkzeuge erheblich.

Nicht immer kompatibel

Hat man sich durch den Dschungel der Alternativen und ihre Installationsvorgänge gekämpft, steht im Idealfall eine lokale Sammlung von Rust-basierten Alternativen zu den GNU- oder BSD-Varianten des Betriebssystems parat. Bei eza beispielsweise fällt auf, dass eza -la nicht klaglos als echtes Drop-in Replacement für ls funktioniert. Die Ausgaben sind sehr ähnlich, aber nicht deckungsgleich. Shellskripte etwa, die die Ausgabe von ls interpretieren wollen, würden zumindest bei eza also schon auf die Nase fallen.

Auf macOS fällt obendrein auf, dass von der versprochenen Geschwindigkeit durch Rust nicht allzu viel zu spüren ist. Im Gegenteil: Eine flotte – nicht professionelle – Messung mit time ergibt, dass eza -la fast doppelt so lange dauert wie ls -la, sprich 0,2 Sekunden gegenüber 0,1 Sekunden. Bei rekursiven Durchläufen mit -laRS in großen, tiefen Verzeichnissen wurden die Unterschiede noch deutlicher (siehe Tabelle „ls -laRS vs. uls -laRS vs. eza -laRS“). Auf Ubuntu 24.04 waren die Zeiten von eza und ls beinahe identisch – hier liefen die Werkzeuge aber auch auf x86_64 und nicht auf AARCH64.

ls -laRS vs. uls -laRS vs. eza -laRS (macOS)
Tools 1. Lauf 2. Lauf
ls 7,709 s 5,311 s
uls 1,475 s 1,315 s
eza 19,420 s 17,945 s

Noch mal etwas anders gestaltet sich die Erfahrung mit procs, dem ps-Ersatz in Rust. Hier wird schnell klar, dass den Entwicklern die Eigenschaft ihres Werkes, als Drop-in-Ersatz für das klassische ps zu fungieren, nicht sonderlich wichtig war. procs -auxw beispielsweise schlägt fehl. procs -a funktioniert, fördert anders als ps a aber nicht eine Liste aller Prozesse des Nutzers auf den Bildschirm, sondern eine Art interaktive Ansicht (siehe Abbildung 3). Sie erinnert eher an die Ausgabe von top. Das wirft procs zumindest als unmittelbaren Ersatz für ps aus dem Rennen.

Für ps gibt es in Rust die Alternative in Form von procs. Das ist allerdings nicht CLI-kompatibel und sieht auch anders aus (Abb. 3).
Für ps gibt es in Rust die Alternative in Form von procs. Das ist allerdings nicht CLI-kompatibel und sieht auch anders aus (Abb. 3).

Eigene Stärken

Zudem kennt das Werkzeug diverse CLI-Parameter nicht, die Administratoren im Alltag unter Linux mit den GNU-Werkzeugen regelmäßig nutzen. ps fauxw beispielsweise zeigt einen Baum der gestarteten Prozesse des Systems mit diversen Zusatzinformationen an. procs aber unterstützt von diesen Parametern nur -a. Eine Baumansicht lässt sich mittels -t erreichen, viele andere ps-Parameter sind gar nicht implementiert. Weder für Shellskripte noch für die alltägliche Nutzung kann bei procs also von einem Eins-zu-eins-Ersatz die Rede sein.

Arbeitet man mit der Riege der In-etwa-Nachbauten, lässt sich das Spiel beliebig wiederholen. difftastic etwa kommt ebenfalls mit Pager-Funktion daher wie procs, beherrscht viele CLI-Parameter von diff nicht und ist beim Aufruf mit diesem entsprechend nicht kompatibel.

Dabei soll an dieser Stelle nicht der Eindruck entstehen, als seien die Rust-Programme, die als Ersatz für die klassischen Shelltools antreten, wegen ihrer teils unvollständigen oder gar nicht gegebenen Kompatibilität zu den historischen Vorbildern schlechter oder minderwertig. Ganz im Gegenteil: Manche Rust-Programme liefern Funktionen, die man sich von den klassischen Vorbildern wünscht.

Der du-Ersatz dua ist dafür ein gutes Beispiel: Dessen Ausgabe ist auch ganz ohne die Angabe von Parametern deutlich übersichtlicher und schicker als jene des normalen du. Will man etwa eine Übersicht der Dateien im lokalen Ordner haben, sortiert nach ihrer Größe und aufsteigend, geht das auf der Shell beispielsweise mit

du -sh ./*  2> /dev/null | sort -h

(siehe Abbildung 4). Oder eben mit dua ohne Parameter (siehe Abbildung 5): Das liefert nicht nur eine übersichtliche farbige Liste, sondern zeigt während der Erhebung der Daten auch den Fortschritt an. Beim klassischen du wartet man stattdessen vor einer leeren Anzeige. Richtig komfortabel wird dua, wenn man es mit dua i im interaktiven Modus startet und damit nicht nur die Festplatte oder SSD durchstöbern, sondern bei der Gelegenheit gleich aufräumen kann. Das Beispiel zeigt: Die Rust-Werkzeuge liefern an vielen Stellen echten Mehrwert.

dua liefert ganz ohne Parameter eine farbige, übersichtliche und nach Größe sortierte Liste der Unterverzeichnisse (Abb. 4).
dua liefert ganz ohne Parameter eine farbige, übersichtliche und nach Größe sortierte Liste der Unterverzeichnisse (Abb. 4).
Um mit du eine übersichtliche und nach Größe sortierte Liste der Unterverzeichnisse zu bekommen, ist schon etwas Geschick oder Erfahrung bei der Wahl der richtigen Parameter vonnöten (Abb. 5).
Um mit du eine übersichtliche und nach Größe sortierte Liste der Unterverzeichnisse zu bekommen, ist schon etwas Geschick oder Erfahrung bei der Wahl der richtigen Parameter vonnöten (Abb. 5).

Coreutils in Rust – als echter Ersatz gedacht

Wer auf der Suche nach einem echten Ersatz für die C-Shellutils ist, muss stattdessen zu den Coreutils des uutils-Projektes wechseln (siehe Tabelle „GNU Coreutils vs. uutils-coreutils“ und ix.de/zmcw). Doch ist hier Vorsicht angesagt: Wer die Werkzeuge installiert, führt tatsächlich die Rust-Werkzeuge aus, wenn er Befehle wie cp oder ls aufruft. Manche Paketmanager umgehen das Problem, indem sie die Tools in einen Pfad außerhalb von $PATH legen und in den Aufrufpfad dann Wrapper packen, die u<Programmname> heißen, oder gleich als u<Programmname> ablegen. Auf macOS unter Homebrew wird aus ls so etwa uls.

GNU Coreutils vs. uutils-coreutils
GNU Coreutils (Debian) uutils-coreutils Rust-Geschwister ​Namensauflösung Beschreibung​
arch arch –​ architecture zeigt die Prozessorarchitektur an
​– b2sum –​ BLAKE2 checksum erzeugt und prüft BLAKE2-Checksummen
​– b3sum –​ BLAKE3 checksum erzeugt und prüft BLAKE3-Checksummen
​– base32 –​ base32 konvertiert in oder von Base32-ASCII-Text
base64 base64 ​– base64 konvertiert in oder von Base64-ASCII-Text
basename basename ​– base part of pathname entfernt Pfad und optional ein Suffix aus einem vollständigen Dateinamen
​– basenc –​ base encoding konvertiert in oder von ASCII-Text
cat cat bat concatenate files verkettet Dateien oder gibt sie auf stdout aus
chcon chcon¹ –​ change context ändert den SE-Linux-Security-Kontext
chgrp chgrp² –​ change group ändert die Gruppe von Dateien oder Verzeichnissen
chmod chmod² ​– change mode ändert die Berechtigungen von Dateien oder Verzeichnissen
chown chown² change owner ändert den Besitzer von Dateien oder Verzeichnissen
chroot chroot² ​– change root directory führt einen Befehl mit einem bestimmten Stammverzeichnis aus
cksum cksum ​– checksum berechnet Prüfsummen und die Anzahl der Bytes von Dateien
comm comm ​– compare and merge vergleicht zwei sortierte Dateien zeilenweise
cp cp xcp copy kopiert Dateien oder Verzeichnisse
csplit csplit –​ context split teilt Dateien abhängig vom Inhalt in mehrere Teile
cut cut choose, hck cut parts of a file entfernt Abschnitte aus jeder Zeile einer Datei
date date –​ system date time zeigt oder setzt die Systemzeit
dd dd ​– dump data konvertiert und kopiert Dateien
df df dysk disk space free zeigt den freien Speicherplatz eines Dateisystems an
dir dir ​– directory wie ls – listet Verzeichnisse und ihre Inhalte auf
dircolors dircolors ​– directory entry colors definiert Farben für ls
dirname dirname –​ directory part of pathname zeigt nur den Pfad eines vollständigen Dateinamens an
du du dua, dust, dutree, erdtree, pdu disk usage zeigt die Speicherplatzbelegung in einem Dateisystem
echo echo ​– echo stdin gibt einen Text aus
env env –​ environment settings setzt Umgebungsvariablen und führt Programme aus
expand expand –​ expand white space konvertiert Tabulatorzeichen in Leerzeichen
expr expr –​ evaluate expression wertet Ausdrücke aus
factor factor –​ evaluate prime factor berechnet Primfaktoren
false false ​– false liefert einen Fehler als Rückgabewert zurück
flock ​– file lock verwaltet Datei-Locks
fmt fmt ​– format text einfacher Textformatierer
fold fold ​– fold bricht Zeilen auf eine bestimmte Länge um
groups groups² –​ groups of a user zeigt die Gruppen an, denen ein Benutzer angehört
hashsum ​– hashsum erzeugt und prüft Checksummen
head head –​ head zeigt nur den Anfang einer Datei an
hostid hostid² ​– host identifier zeigt die hexadezimale ID des Rechners an
hostname ​– hostname setzt oder zeigt den Namen des Rechners an
id Id² ​– user’s identity zeigt die Nutzer- und Gruppeninformationen eines Benutzers an
install install² ​– install kopiert Dateien und Verzeichnisse und setzt Attribute
join join ​– join lines of two files vereinigt Zeilen aus zwei Dateien mit einem gemeinsamen Feld
kill² –​ kill process sendet Signale an Prozesse
link link ​– link to a file erstellt einen Hardlink auf eine Datei
ln ln –​ link node erstellt Hard- und Softlinks zu Dateien oder Verzeichnissen
logname logname² –​ login name zeigt den Loginnamen des Nutzerkontos an
ls ls exa, lsd, nat list directory content listet Verzeichnisse und ihre Inhalte auf
md5sum md5sum ​– MD5 checksums berechnet und vergleicht MD5-Prüfsummen
mkdir mkdir –​ make directory erstellt Verzeichnisse
mkfifo mkfifo² ​– make ‘first in first out’ erstellt Pipes (FIFOs)
mknod mknod² –​ make node erstellt Gerätedateien
mktemp mktemp ​– make temporary file or directory erstellt temporäre Daten oder Verzeichnisse
more ​– more zeigt den Inhalt einer Datei an
mv mv ​– move verschiebt Dateien oder Verzeichnisse respektive benennt sie um
nice nice² ​– be nice ändert die Priorität eines Prozesses
nl nl ​– number lines fügt einer Datei Zeilennummern hinzu
nohup nohup² ​– no hang up führt einen Befehl aus, der auch nach dem Abmelden weiterläuft
nproc nproc ​– number of cores for a process zeigt die für einen Prozess verfügbare Zahl der CPU-Kerne an
numfmt numfmt ​– number format konvertiert Zahlen in menschenlesbare Formate
od od ​– octal dump listet den Inhalt von Dateien in verschiedenen Formaten auf, etwa hexadezimal
paste paste –​ paste lines of files vereinigt Zeilen von Dateien
pathchk pathchk² –​ path check prüft Dateinamen auf Portabilität
pinky pinky² –​ Pinky – lightweight finger zeigt Informationen zu einem Benutzer an
pr pr –​ printing format formatiert Dateien zum Drucken
printenv printenv –​ print environment settings zeigt Umgebungsvariablen an
printf printf ​– print formated gibt Daten formatiert aus
ptx ptx ​– permuted index erstellt einen permutierten Index von Dateiinhalten
pwd pwd ​– print working directory zeigt das aktuelle Arbeitsverzeichnis an
readlink readlink ​– read link zeigt Informationen zu einer symbolischen Verknüpfung an
realpath realpath ​– real path zeigt den tatsächlichen Pfad an
rm rm rip remove löscht Dateien
rmdir rmdir –​ remove directory löscht Verzeichnisse (auch rekursiv)
runcon runcon¹ –​ run with context führt einen Befehl in einem bestimmten SE-Linux-Kontext aus
seq seq ​– sequence gibt eine Folge von Zahlen aus
sha*sum sha*sum ​– SHA* checksums berechnet und vergleicht verschiedene SHA*-Prüfsummen
shred shred ​– shred file löscht Dateien unwiederbringlich durch Überschreiben
shuf ​– shuffle mischt Zeilen durch
sleep sleep ​– sleep wartet eine bestimmte Zeit
sort sort ​– sort lines of a file sortiert Zeilen einer oder mehrerer Dateien
split split ​– split file content teilt eine Datei in Stücke auf
stat stat² ​– state of inode gibt Dateisysteminformationen zu einer Datei aus
stdbuf² ​– standard streams buffer verändert die Buffer von stdin, stdout und stderr für ein Kommando
stty stty² ​– set teletype setzt Terminaleinstellungen
sum sum ​– checksum zeigt Prüfsummen und Anzahl der Blöcke einer Datei an
sync sync ​– synchronize data synchronisiert die Dateisystempuffer mit dem Massenspeicher
tac tac –​ reverse cat schreibt die Zeilen einer Datei in umgekehrter Reihenfolge auf stdout
tail tail ​– show tail zeigt nur das Ende einer Datei an
tee tee –​ tee connector zweigt den Datenstrom in eine Datei ab
test, [ ] test, [ ] –​ test prüft Dateitypen und wertet Ausdrücke aus
timeout timeout² –​ timeout begrenzt einen Befehl auf ein Zeitfenster
touch touch –​ touch file attributes ändert Zeitstempel von Dateien und Verzeichnissen und legt leere Dateien an
tr tr ​– translate characters ersetzt oder löscht Zeichen in einer Datei
true true –​ true liefert wahr als Rückgabewert
truncate truncate –​ truncate verändert die Größe einer Datei
tsort tsort –​ topologic sort führt eine topologische Sortierung aus
tty tty² ​– teletype zeigt den Namen des Terminals an
uname uname –​ unix name zeigt Informationen zum Betriebssystem an
unexpand unexpand –​ unexpand tabs konvertiert Leerzeichen in Tabulatorzeichen
uniq uniq huniq show unique lines löscht oder meldet mehrfach vorkommende Zeilen aus einer sortierten Datei
unlink unlink ​– unlink löscht eine Datei mit der unlink-Funktion
​– uptime ​– system up time zeigt die uptime des Systems, die Zahl der Nutzer und Jobs an
users users² ​– users zeigt die derzeit am Rechner angemeldeten Benutzer an
vdir vdir –​ variant of dir Variante von dir
wc wc ​– word count zählt die Bytes, Wörter und Zeilen einer Datei
who who² who zeigt Informationen über die derzeit am Rechner angemeldeten Benutzer an
whoami whoami ​– who am i zeigt die eigene Benutzeridentität an
yes yes ​– yes gibt wiederholt einen Text aus, per default „y“
¹ nur Linux; ² nur Linux und macOS (kein Windows)

Wer tatsächlich dauerhaft auf die Rust-Werkzeuge umsteigen möchte, fügt im ersten Fall den Ordner /usr/local/opt/uutils-coreutils/libexec/uubin der Liste der Pfade hinzu, in denen die Shell nach Programmen sucht. So oder so gilt aber: Wer die Rust-Version der Coreutils installieren möchte, tut vermutlich gut daran, zunächst in einer virtuellen Instanz zu experimentieren.

Im Test haben sich die Werkzeuge des Coreutils-Pakets von uutils dabei durchaus bewiesen. Das gilt zunächst für die CLI-Kompatibilität mit den GNU-Werkzeugen: Sämtliche Parameter für ls existieren in der Rust-Version und führen zur selben Ausgabe wie beim C-Gegenstück. Die Ausgabe von df ist identisch und lässt sich durch verschiedene Parameter steuern.

Flott unterwegs

Auch in Sachen Geschwindigkeit konnten die Werkzeuge aus der Coreutils-Sammlung von uutils punkten. Schnelle Messungen mit time ergaben, dass etwa der Aufruf von ls -ltR deutlich langsamer war als jener von uls -ltR. Hier betrug der Unterschied bei einem großen Verzeichnis mit vielen Unterverzeichnissen mehr als eine Sekunde (siehe auch Tabelle „ls -laRS vs. uls -laRS vs. eza -laRS“).

Freilich spielt der Kernel des Systems zusammen mit dem genutzten Dateisystem eine große Rolle bei der Frage nach der Dauer der Ausführung solcher Befehle. Zumindest kamen beim Schnelltest in der Redaktion aber dieselben Ordner und Kommandos zur Anwendung, um sowohl die klassischen Coreutils in C als auch ihre Rust-Pendants zu testen. Obendrein gelten die Vorteile auch nicht bei allen Programmen.

Wer die Coreutils in Rust ausprobieren möchte, findet im Netz für die meisten Distributionen fertige Pakete oder eine andere Form der Integration – auch für Debian GNU/Linux, und das ist alles andere als ein Zufall. Denn hinter den uutils-coreutils steht Sylvestre Ledru, Präsident der Mozilla-Foundation, Debian-, Ubuntu-, LLVM-, Clang-Entwickler und Rust-Fan, der die Arbeit an der Werkzeugsammlung während der Coronapandemie begann.

In der Community verankert

In einem Vortrag während der FOSDEM 2023 erklärte er die Beweggründe: Neben den erwähnten Vorteilen in Sachen Sicherheit sei Rust vor allem extrem gut portierbar. Obendrein stünden in Rust nativ viele Funktionen zur Verfügung, die man in C erst mühsam nachbauen muss. Die walkdir-Funktion etwa ermöglicht das Iterieren durch Dateisystembäume und ist die perfekte Grundlage für Werkzeuge wie cp oder rm. Einen großen Teil ihrer Geschwindigkeitsvorteile erreichen die uutils-coreutils, indem sie auf eben diese Funktionen zurückgreifen. In Form von lscolors steht – das ist fast schon witzig – in Rust sogar eine Funktion bereit, die die Ausgabe in dieselben Farben tunkt wie das ls aus den GNU Coreutils.

Sein ursprüngliches Ziel, ein Debian-System auf Basis seiner Rust-Werkzeuge zum reibungslosen Start zu bringen, hat Ledru dabei schon längst erreicht. Noch betrachtet er die Entwicklung aber nicht als abgeschlossen – noch bessere Kompatibilität zu den Coreutils sei das Ziel, und ein Quäntchen Performance sei hier und dort wohl auch noch aus den Werkzeugen herauszupressen. Wer die uutils-coreutils installiert, merkt im Alltag jedenfalls nur noch sehr selten, dass er nicht die GNU-Version der Werkzeuge nutzt.

Auch lizenzrechtlich haben die grundsätzlich sehr strengen Debian-Entwickler an den uutils-coreutils nichts auszusetzen, denn Ledru, immerhin ja einer der Ihren, hat sein Werk unter die MIT-Lizenz gestellt, die kaum irgendeine Art und Weise der Verwendung ausschließt. Ähnlich verhält es sich übrigens auch mit jenen Werkzeugen, die nicht zu den uutils-coreutils gehören: Hier findet sich zwar ein recht bunter Strauß an Lizenzen, ihnen allen ist aber gemein, dass sie als frei im Sinne der FSF, des GNU-Projekts und der Debian Free Software Guidelines gelten.

Wer die Rust-Variante der Coreutils ausprobieren möchte, findet auf der Website des Projekts dafür die nötigen Informationen (siehe ix.de/zmcw). Der einzige Wermutstropfen: Zu den Coreutils gehören alltägliche Werkzeuge wie ls und cp, das allseits beliebte grep fehlt aber ebenso wie ein Nachbau von awk oder sed. Hier muss man im Zweifelsfall also doch wieder auf Werkzeuge aus der Community zurückgreifen, deren Ziel nicht die vollständige Kompatibilität mit den jeweiligen GNU-Varianten der Programme ist – wie etwa bei procs oder eza.

Kleines Trostpflaster: Immerhin arbeitet das uutils-Projekt an zwei weiteren Sammlungen: Noch ganz am Anfang stehen die uutils-diffutils, und von den avisierten Werkzeugen find, locate, updatedb und xargs der GNU Findutils existieren zumindest schon Rust-Nachbauten von find und xargs.

Fazit

Perfekt komfortabel bettet man sich im Land der Rust-Werkzeuge auf der Shellebene bis dato also noch nicht, auch wenn sich die meisten Funktionen bereits durch bestehende Werkzeuge ersetzen lassen. Die Daten und Messwerte, die sich aus den bereits nachgebauten Rust-Werkzeugen ergeben, machen aber Lust auf mehr. Bis es beispielsweise einen Eins-zu-eins-Ersatz für diff gibt, dürfte es nur eine Frage der Zeit sein. Administratoren sollten nicht davor zurückschrecken, neue Pfade zu beschreiten und insbesondere den uutils-coreutils eine Chance zu geben.

Auch bei den In-etwa-Nachbauten und den Neuschöpfungen finden sich interessante, moderne und performante Werkzeuge, die Admins sich wiederholende Aufgaben abnehmen oder diese komfortabler gestalten. Dabei bleiben die Entwickler nicht bei den üblichen Datei- und Prozesswerkzeugen für die Kommandozeile stehen. Moderne Terminal-Emulatoren, Shells, Dateimanager, Kalkulatoren, Netzwerk- und Entwicklerwerkzeuge sowie Editoren und Viewer etwa für Text-, Markdown-, CSV- und Binärdateien können ebenso den Arbeitsalltag erleichtern (siehe Tabellen dazu). Wir werden einige von ihnen in kommenden Heften separat vorstellen. (sun@ix.de)

Terminal-Emulatoren, Shells und Shellerweiterungen in Rust
Rust-Programm vergleichbares C-/C++-/C#-Pendant Beschreibung
Terminal-Emulatoren​​
Alacritty termite anpassbarer Terminal-Emulator mit vim-Modus, Suche, Multi-Window- und Mausunterstützung
Rio ​kitty GPU-beschleunigter Alacritty-Ableger mit hoher Farb- und Bildauflösung
sshx kollaboratives Terminal mit HTTPS-Sharing
Wezterm ​kitty GPU-beschleunigter Terminal-Emulator und -Multiplexer mit hoher Farb- und Bildauflösung
Zellij tmux Terminal-Multiplexer
Shells​​
ion dash schnelle, moderne Shell
nushell shell strukturierte Shell mit erweitertem Piping für den Umgang mit struktierten Daten
Shellerweiterungen​​
atuin Ctrl-r erweiterte Shell-History mit SQLite-Backend und zusätzlichen Kommandoinformationen
IntelliShell erweiterte Kommandovervollständigung für Bash, Zsh, Fish und PowerShell, wie IntelliSense für Shells
mcfly Ctrl-r schnelle Suche in der Shell-History mit Priorisierung der Ergebnisse durch ein kleines neuronales Netz
Shellharden ShellCheck Bash-Syntaxhighlighter mit semiautomatischer Korrektur
starship Spaceship anpassbarer Shell-Prompt
Dateimanager​ in Rust
broot Midnight-Commander-ähnlicher, umfangreicher Dateimanager mit Farben, Dateiviewern, Kommandozeile et cetera
felix schneller, einfacher Dateimanager mit vim-ähnlicher Handhabung
joshuto ranger-ähnlicher Dateimanager
xplr Dateimanager und interaktiver Orchestrator von Dateiwerkzeugen
yazi Dateimanager mit asynchronem Non-blocking-I/O
CLI-Rechner in Rust​
cpc Rechner mit Einheitenumrechner
eva bc-Klon mit Syntaxhighlighting und persistenter History
fend Rechner mit Einheitenumrechner
kalker wissenschaftlicher Rechner mit Variablen, Funktionen, Differenzial- und Integralrechnung
Netzwerk-, Web- und E-Mail-Helfer in Rust
Rust-Werkzeuge vergleichbare C-Pendants Beschreibung
Netzwerkhelfer​​
bandwhich iftop, bmon, tcpmon Netzwerkauslastungsmonitor
dog dig DNS-Client
drill jMeter HTTP-Lasttester
lemmeknow ​– String-Analyzer, etwa für Netzwerkpakete oder Malware
miniserve –​ schlanker Dateiserver über HTTP mit TLS und HSTS
RustScan –​​ adaptiver schneller Portscanner
Webhelfer​​
ffsend Firefox Send einfaches und sicheres Datei-Sharing
htmlq sed, awk, grep HTML-Content-Extrahierer
hyperlink ​–​ schneller URL-Checker
mdBook –​​ erstellt moderne Onlinebücher in TOML aus Markdown-Dateien
monolith –​​ bündelt Webseiten in einzelnen HTML-Dateien
xh httpie performanter HTTP-Client
E-Mail-Werkzeuge​​
himalaya ​–​ E-Mail-Client
mrml mjml Mailjet Markup Language
Entwicklungswerkzeuge und -helfer in Rust
Rust ​C-Pendants Beschreibung​
deno_lint ESLint performanter Linter für JavaScript und TypeScript
difftastic diff vergleicht Dateien auf Basis der Syntax von über 30 Programmiersprachen
dprint Prettier erweiterbare und konfigurierbare Codeformatierungsplattform
fastmod codemod Werkzeug zum Refaktorieren großer Codemengen, sed & diff in großen Verzeichnishierarchien
fnm nvm einfacher, schneller Node.js-Versionsmanager
frum rbenv moderner Ruby-Versionsmanager
gitcliff anpassbarer Changelog-Generator
gitui lazygit Terminal UI für git
jaq jq JSON-Query-Language-Tool
jless –​ JSON-Viewer mit Suchfunktion
jql jq JSON-Query-Language-Tool
just make Command-Runner mit Überschneidungen zu make
ripsecrets Secrets-Scanner für Sourcecode
RSLint ESLint performanter Linter für JavaScript und TypeScript
ruff ​– performanter Linter für Python
ruplacer ​– sucht und ersetzt Text in Dateien
tokei cloc zählt Code
volta nvm schneller JavaScript-Tool-Manager
watchexec –​ automatischer Command-Runner für Unit-Tests und Linter oder Syntax-Checker
Editoren und Viewer
Rust bekanntestes C-Pendant​ ​Beschreibung
Text und Code​​
amp vim durch vim inspirierter Texteditor
helix kakoune/neovim durch Kakoune/Neovim inspirierter Texteditor
kibi kilo minimalistischer Texteditor mit weniger als 1024 Zeilen Code
lapce vim vim-ähnlicher Code- und Texteditor mit integrierter Kommandozeile
pepper vim schlanker Code- und Texteditor
zed atom, vim schneller Multiplayer-Codeeditor mit optionalem vim-Modus von den Entwicklern des Codeeditors Atom
zee emacs moderner, durch emacs inspirierter Texteditor
Markdown
inlyne GPU-beschleunigter Markdown- und HTML-Viewer
mdcat mdless cat für Markdown
Hex​​
heh dhex Terminal-Hexeditor, der Daten in Hex und ASCII schreibt
hexyl hexdump Hexviewer mit Syntaxhighlighting für die Byte-Kategorien
teehee bvi durch vim, Kakoune und Hiew inspirierter Hexviewer
CSV​​
csvlens sc, sc-im interaktiver CSV-Datei-Viewer
qsv xsv Werkzeug zum Bearbeiten, Analysieren und Bereinigen von CSV-Dateien, Fork von xsv
xsv xsv, csvkit Werkzeug zum Bearbeiten, Analysieren und Bereinigen von CSV-Dateien

Kommentare lesen (1 Beitrag)