CLI-Adventskalender, Tag 4: fzf

CLI-Adventskalender: fzf

Avatar von Eric

Wir schreiben den vierten Dezember und wollen euch nicht lange auf die Folter spannen. Heute geht es um: fzf.

Es gibt Werkzeuge aus dem Unix-Umfeld die sich anfühlen wie Relikte der Altvorderen. Das sind Programme, die schon immer da gewesen sind und deren Nutzen wir in staubigen Büchern dokumentiert sehen; aus einer Zeit, bevor es DSL-Internet gab.

Und dann gibt es Werkzeuge die sich so gut in eine Lücke in dieses Ökosystem einfügen, dass sie nicht nur einen Platz dort finden, sondern gleich alles ringsherum transformieren. So wie fzf zum Beispiel.

fzf

fzf ist ein Fuzzy-Searcher. Es nimmt eine lange Liste an Strings an, generiert ein Auswahlmenü mit Volltextsuche und partiellem Matching und gibt dann die Auswahl wieder als Standardoutput aus.

Ähm, Eric … das klingt ein bißchen unterwältigend, nach dem ganzen Hype den Du da fabriziert hast.“ Schaut einfach auf die Demo.

kill -9 $(ps aux | fzf | awk '{print $2}')

Damit fzf seine volle Awesomeness entfaltet, braucht man derer vier Zutaten:

  1. Ein Kommando, das Unmengen von Daten auf jeweils einer Zeile pro Datensatz generiert. In diesem Fall ps aux für eine Liste der laufenden Programme.
  2. Da fzf einfach nur die ausgewählte Zeile ausspuckt, müssen wir den Output noch ein wenig zurechtstutzen, hier mit awk („Gib uns genau das zweite Wort.“).
  3. Das Kommando, das die Auswahl entgegennimmt; in diesem Fall kill -9 („Erschieße bitte folgenden Prozess, bevor er Piep sagen kann.“)
  4. Ein Konstrukt aus Pipes und Command Substitution, dass den ganzen Output wasserdicht wie ein IHK-geprüfter Klempner überleitet.

Jetzt können wir damit ein bißchen Spaß haben, zum Beispiel mit cd $(find -d | fzf).

Das ist perfekt zum Navigieren von komplexen Verzeichnisbäumen, deren Inhalt man nicht so genau kennt. Das geht natürlich auch mit anderen Befehlen:

sudo cp new_config_file.conf $(find -d /etc | fzf)

Wenn man eine Config-Datei installieren will und den Ordner nicht findet.

Und als Anlehnung an meinen vorherigen Post zu SSH

ssh $(cat ~/.ssh/config | grep "Host " | awk '{print $2}' | fzf)

Welchen Namen hatten wir dem System nochmal gegeben?

Schummeln im großen Stil

Fuzzy-Searching ist heute in den meisten IDEs mit drin. Längst schon muss man sich nicht mehr durch Menüs durchklicken oder obskure Finger-Yoga-Tastenkürzel auswendig lernen. Wer in VSCode Ctrl + Shift + P drückt, hat alle Kommandos der IDE in einer Fuzzy-Search, wer Ctrl + P drückt, kann eine Datei mit einem bestimmten Namen finden (Ctrl + Shift + A in Intellij für Kommandos und zweimal Shift, um gleich alles auf einmal zu durchsuchen, Kommandos, Dateien, Symbole, etc). Kann man sowas auch im Terminal haben?

Aber natürlich.

Man gehe zu einem beliebigen Spickzettel-Repo (devhints.io, TLDR, cheat.sh, etc) und baue sich einen Spickzettel, der beispielsweise so aussieht:

git branch              # shows all the branches (current branch is shown with a star)
git branch my-branch    # creates my-branch
git branch -d my-branch # deletes my-branch
git checkout my-branch # switches to my-branch
git merge my-branch     # merges my-branch to current branch
git push origin :my-branch         # delete remote branch

Credit an das fzf-cheatsheets-Tool, dass eine fertige Lösung für das bietet, was wir gleich zu Fuß bauen. Mit ein bißchen liebevollem Frickeln haben wir dann die gesamte Magic direkt mit einem Shortcut in unserer Shell.

fzf_magic() {
    local selected_command
    selected_command=$(cat /home/eric/cheatsheet.txt | fzf | cut -d '#' -f 1)
    READLINE_LINE="${READLINE_LINE}${selected_command}"
    READLINE_POINT=$((READLINE_POINT + ${#selected_command}))
}
bind -x '"\C-f": fzf_magic'

Das schöne an solchen Lösungen ist:

  1. Sie skalieren beliebig hoch. Solange die Syntax eingehalten wird, kann ich tausende Befehle in meinem Spickzettel haben.
  2. Sie können situativ nützliche Informationen liefern. Mit ein bißchen Disziplin (ja, ja … ich weiß) packe ich die Befehle, mit denen ich meine Dockerumgebung repariert habe, gleich ins Projektrepo. Das bringt uns direkt zu …
  3. Sie sind teilbar. Derartige Listen kann man super als Team pflegen und nutzen.
  4. Sie sind „low-tech“. Auch wenn bestehende Tools aus der Mode kommen, wird die Liste immer noch nützlich sein.

Und wenn man irgendwann eine Sammlung mit hunderten von Shellskripten hat, verliert man mit einer derartigen Lösung nie wieder die Übersicht.

Benutzt eure Fantasie!

Die meisten Artikel, die ich hier schreibe, zeigen weniger bekannte Features von sehr bekannten Tools. Dieses Mal gebe ich euch ein Tool, dessen Wirkung davon abhängt, dass ihr euren persönlichen Anwendungsfall dafür findet.

Wollt ihr so eure Bookmarks organisieren?

cat ~/bookmarks.txt | fzf | cut -d '#' -f 1 | xargs -I {} firefox "{}"

Oder eure mp3-Sammlung?

find ~/Music -type f | fzf | xargs -I {} cvlc "{}"

Ganz gleich ob ihr Todo-Listen, Notizen, E-Mails, Prozesse oder virtuelle Maschinen filtert: fzf hilft euch, zeitnah durch riesige Datenmengen durchzukommen.

Shell-Weisheit des Tages
Terminals sind anpassbar

Als ich Teenager war, hatte ich eine Ausgabe der PC Welt in der Hand, auf dessen mitgelieferter CD-ROM der Windows Resource Hacker war. Mit einem Mal konnte ich auf kompilierten GUI-Anwendungen Werbung ausblenden (Das war der Use Case, den die PC Welt vorschlug …), Menüs umbenennen, unnötige Knöpfe entfernen. Häufig arbeiten wir als User mit den Karten, die uns irgendein weit entferntes UX-Team austeilt. Oft haben wir Programme, in denen wir nicht mal Hotkeys umdefinieren dürfen.

Kontexte sind komplex. Ein Tool, dass für möglichst viele Anwender nützlich sein muss, steht im dringenden Verdacht, für fast alle Nutzer überladen zu sein. Die Shell ist hier anders. Ihre Funktionen sind unsichtbar. Jeder Befehl ist anpassbar: alias ls="ls -la"

Informationen können in Umgebungsvariablen hinterlegt werden.

export USERNAME="eric"

Und Umgebungsvariablen können in der .bashrc-Konfigurationsdatei hinterlegt werden, um einfach immer automatisch gesetzt zu sein. Tatsächlich sind die meisten Terminaltools (und Linux-Desktopanwendungen) mit User-spezifischen Konfigurationsdateien konfigurierbar. Ein einfaches Suchen nach „dotfiles“ auf Github bietet eine Unzahl an Beispielen (ein Thema auf das ich hinter späteren Türchen unseres Adventskalenders noch näher eingehen werde). Ganz zu schweigen von Skripten, die wir schreiben können, oder den tausenden von Tools, die wir evaluieren können. Schnell setzt hier Überforderung ein.

Also, welche Shortcuts möchte man setzen? Hierzu muss man sich selbst verstehen; die eigenen Aufgaben und die Gewohnheiten. Mein Rat ist folgender: Keine quietschenden Türen. Wenn irgendwas im Haus kaputt geht einfach mal kurz Zeit nehmen, einen Reparaturversuch zu unternehmen. Jedes Mal, wenn man beim Arbeiten mentale Reibung spürt weil irgendetwas mühseliger ist als es sein sollte, gilt es einmal am Tag bis zu zehn Minuten zu investieren. Einmal googlen. Einmal ChatGPT fragen. Einmal einen Blick in die manpages oder API-Dokumentation werfen.

Für mich zumindest hat das sehr gut funktioniert. Ich war überrascht, wie schnell sich Dinge aufsummiert haben.

Avatar von Eric

Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert


Für das Handling unseres Newsletters nutzen wir den Dienst HubSpot. Mehr Informationen, insbesondere auch zu Deinem Widerrufsrecht, kannst Du jederzeit unserer Datenschutzerklärung entnehmen.