Merke dir weniger, weiss aber mehr mit State-of-the-Art Cheatsheets

21.09.2022Raffael Schneider
Tech Rust CLI Productivity cheatsheets

Wer kennt das Problem schon nicht? Man ist gerade mit einem technischen Stakeholder im Screensharing und versucht, schnell noch einen Befehl in der Kommandozeile auszuführen, um die gewünschte aber fehlende Informationen herauszubekommen. Man erinnert sich gerade noch an die Befehlsignatur, aber die danach kommenden Parameter sind auf Anhieb nicht mehr präsent. Man tippt unverholfen die Tab-Taste, mit der Hoffunung, dass die Autovervollständigung automatisiert die fehlenden Flags komplettiert, es kommen aber nur offensichtlich falsche Vervollständigungsversuche zustande. Die --help-Flag ist leider nur halbfertig implementiert, so ruft man als nächtes noch die Anleitung des Befehls mit man auf und bemüht sich, den entsprechenden Eintrag mit den gewünschten Flags per Suchfunktion zu finden. Vergebens. Schlussendlich per Tastenkombination in den Webbrowser geswitched, scrollt man sich nach einer schnellen Google-Suche auf Stackoverflow durch eine Vielzahl von Antworten durch. 🫠

Selbstverständlich findet man dann wohltuenderweise natürlich die Lösung des eigentlichen Ausgangsproblems. Nicht selten steht im Anschluss eine ähnliche, aber doch genug abweichende Anwendung des nächsten Kommandozeilenbefehls an, und der ganze Prozess beginnt wieder von vorne. Sofern man diese Befehle nicht tagtäglich nutzt, wird einem klar, dass man da vielleicht ein wenig Nachholbedarf hat. Aber lohnt sich dieser Aufwand überhaupt? Nicht unbedingt, wenn man Cheatsheets hat!

Solche zeitkritische Situationen ergeben sich nicht nur in der Kommandozeile, sie liefern auch bei der aktiven Programmierung oder Anwendung eines Shortcuts in einem GUI der Wahl unbeholfene Verfangenheit, welche nicht selten auch an der eigenen Kompetenzwahrnehmung nagt.

Schonmal vorausgeschickt; solche Momente liegen nicht zwingend am eigenen Kompetenzmangel, sondern sind lediglich ein täglicher Ausdruck der schnell voranschreitenden Entwicklung des Tech-Stacks, den wir Entwickler und IT-Enthusiasten beim Hinzukommen neuer Komponenten, Tools oder Techniken stets neu meistern müssen. Sei also nicht niedergeschlagen, wenn die vorige Beschreibung eines möglichen Szenarios bei dir schon für Frust gesorgt hat, sondern sieh es als Zeichen, dass du dort noch etwas verbessern kannst, um für einen effizienteren und transparenteren Workflow zu sorgen und ultimativ Zeit zu sparen. Genau das bringt uns auf das Kernthema des heutigen TechUp, nämlich, wie man mit modernen Cheatsheets genau diesen Workflow optimaler gestalten und sich besser auf das zu lösende Problem fokussieren kann, und somit auch weniger auf das Ausweniglernen eines archaischem Parameterflags eines CLI-Tools konzentrieren muss, welches man sowieso gefühlt nur einmal im Monat nutzt.

Mehr wissen mit Cheatsheets 🗒😎

Cheatsheet steht auf Deutsch für Spickzettel und ist nicht zwingend, wie der Name auf Englisch suggeriert, ein Mittel um zu betrügen. Cheatsheets sind beispielsweise Post-It’s, welche auf dem Unterkante des Monitors kleben und, neben terminlichen Remindern, oft genutzte Prozesse in Form von kurzen Stichwörtern ersichtlich machen. Somit wird der Blick auf das Post-It zum Werkzeug, dass den eigenen Workflow um wenige Sekunden schneller und effizienter macht. Solche Spickzettel oder Cheatsheets gehen natürlich auch digital und finden gerade in der IT häufig Anwendung.

Tech-fokussierte Cheatsheets sind zwar keine Neuheit, haben aber in den letzten Jahren extrem an Flexibilität und Möglichkeiten zugenommen und sind in einem modernen Workflow gar nicht mehr wegzudenken. Gerade hier möchte ich gerne ich eine Unterscheidung vornehmen und die unterschiedlichen Kategorien von Cheatsheets wie folgt aufteilen:

  • Fokus auf UNIX/Linux-Kommandos und CLI-Tools: Diese Cheatsheets sind eine Anwenderfokussierte Sammlung gänginger Anwendungsbeispiele von Kommandozeilenbefehlen, die oft mit Platzhalter-Elementen versehen sind. Diese lassen sich mit Keywords weiter verfeinern, man kann damit also so ziemlich alle Anwendungsfälle eines gegeben CLI-Tools darstellen lassen.
  • Fokus auf GUI und Shortcuts: Diese Cheatsheets sind von Natur aus visuell und zeigen eine vorselektierte suchbare Ansammlung von Shortcuts und GUI-Prozessen, mit denen man die gewünschte GUI bedienen kann. Diese sind definitiv nützlich, stellen aber nicht den Hauptfokus des heutigen TechUp dar.
  • Fokus Programmiersprachen und idiomatische Programmier-Patterns: Diese Cheatsheets sind Programmiersprachenabhängig und haben das Ziel, gängige Funktionen, Code-Snippets oder gar Patterns aufzuzeigen.
  • Fokus auf generelle IT-Themen durch Nutzung von Knowledge-Markets und Q&A-Plattformen: Diese Cheatsheets nutzen eine API zu gängigen Q&A-Plattformen wie Stackoverflow oder Serverfault und suchen die relevanteste Antwort gleich raus. Diese können auf Kommandozeile oder Programmierung getrimmt sein, beinhalten aber oft auch weitere tangentielle IT-Themen. Die Wartung solcher Knowledge-Datenbanken ist komplex, diese Tools sind aber in der heutigen Fassung durchaus nutzbar und leisten nicht selten das gewünschte Ergebnis.

So, bevor wir mit den eingentlichen Cheatsheets loslegen, möchte ich noch erwähnt haben, dass die verschiedenen Tools, die ich hier vorstelle auf unterschiedliche Knowledge-Basen zugreifen, und es für eine gegebene Knowledge-Basis oft mehrere Clients geben kann. Hier werde ich versuchen einen Überblick der wichtigsten Quellen und den dazugehörigen relevanten Clients zu geben.

Coreutils-Cheatsheet mit eg

eg ist ein relativ einfaches Cheatsheet, welches in Python geschrieben ist und Cheatsheets für die UNIX-Coreutils wie cp oder strace bietet. Die Knowledge-Basis wird bei der Installation gleich mitinstalliert und ist im Grunde eine Ansammlung von Markdown-Dateien. Diese Sammlung ist auf dem diesem GitHub-Repository einsehbar.

Installation von eg

eg lässt sich per Python-Package-Manager pip oder für MacOS mit brew installieren. Hier nehmen wir man den brew-basierten Installationsweg:

1
$ brew install eg-examples

Nutzung von eg

Die Nutzung von eg ist “deadsimple”:

1
$ eg <program>

Man kann auch eigene Markdown-Dateien anlegen, um das Set an suchbaren Begriffen zu erweitern. Was für die Nutzung von eg spricht ist definitv dessen Einfachheit und Übersichtklichkeit. Ein kleines aber feines Cheatsheet für den gelegentlichen UNIX-Nutzer.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
$ eg tar
# tar
# tar

extract .tar file

    tar vfx archive.tar


unzip and extract .tar.gz or .tgz file

    tar vfxz g_zipped_archive.tar.gz


turn directory into a .tar file

    tar vfc tarred_directory.tar directory


turn directory into g-zipped directory

    tar vfcz z_zipped_directory.tar.gz directory



# Basic Usage

`vf` means verbosely list files (`v`) and use a file (`f`), not `stdin`.
These appear in most commands.

Untar a file:

    tar vfx <tar-file-to-extract>


Create a tar file from a directory:

    tar vfc <name-of-tar-file> <directory-to-tar>



# Remembering the Flags

`tar` is very finicky. Flags don't need to be prepended by a hyphen, but are
instead bundled into the first word on the command line. A leading hyphen will
break some implementations or require an order. For example, `tar vfx` might
work while with a hyphen it would require `tar -xvf`, with the `x` flag first.
You can get maximum portability is you never use the hyphens, so examples here
are shown without the hyphen.

You'll almost always want `vf`. `v` verbosely lists files as they are
manipulated, and `f` means you're reading from a file, not `stdin`. You can
remember `vf` if you remember that `tar` is Very Finicky: `vf`.

Extract things from a tar file with `x` for extraction. Compress things to a
tar file with `c` for compress.

And you'll have to just remember that g-zipping is `z` and b-zipping is `j`.



# Tarring

Compress directory (`c`) into g-zipped (`z`) directory:

    tar vfcz z_zipped_directory.tar.gz directory

CLI-Cheathsheet mit tldr

Die nächste Steigerung von eg ist tldr. tldr, oder genauer auch tldr-pages genannt, ist ein Git-basiertes Sammelsurium von kurzen, aber hilfirechen Man-Pages für alle gängigen Command-Line-Utils. tldr deckt somit nicht nur die Coreutils wie eg ab, sondern so ziemlich alle erdenkliche Kommandozeilenbefehle. Zudem ist tldr internationalisiert und bietet tldr-pages neben Englisch auch auf Sprachen wie Deutsch, Französisch oder Spanisch an.

Installation von tldr

Um tldr nutzen zu können, brauchen wir einen Client, welcher die Pages aus Github lesen kann. Da gibt es wahlweise einen Node.js-basierten Client, welcher über npm install -g tldr installierbar ist, oder einen Python-basierten Client, welcher mit pip3 install tldr zu installieren wäre. Ich entscheide mich hier aber für ein Rust-basiertes Binary als Client, welches tealdeer heisst:

1
$ cargo install tealdeer

Nutzung von tldr

Tealdeer als Client kann die tldr-pages aus dem GitHub-Repository lokal zwischenspeichern. Somit ist die Performance nach erfolgreichem Update viel schneller als bei alternativen Clients. Das kann man einfach per tldr --update forcieren.

Die Nutzung von tealdeer/tldr ist genau wie bei eg “deadsimple”:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
$ tldr xcodebuild

  Build Xcode projects.
  More information: <https://developer.apple.com/library/archive/technotes/tn2339/_index.html>.

  Build workspace:

      xcodebuild -workspace workspace_name.workspace -scheme scheme_name -configuration configuration_name clean build SYMROOT=SYMROOT_path

  Build project:

      xcodebuild -target target_name -configuration configuration_name clean build SYMROOT=SYMROOT_path

  Show SDKs:

      xcodebuild -showsdks

Das Beispiel ist bewusst eine MacOS-spezifische Darstellung, um zu zeigen, dass auch archaische Befehle abgedeckt sind. tldr-pages beinhalten nicht nur reine Beispiele von Kommandozeilenbefehlen, sondern zeigen auch hilfreiche Shortcuts auf. Hier ein Beispiel mit tmux:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ tldr tmux

  Terminal multiplexer. It allows multiple sessions with windows, panes, and more.
  See also `zellij` and `screen`.
  More information: <https://github.com/tmux/tmux>.

  Start a new session:

      tmux

  Start a new named session:

      tmux new -s name

  List existing sessions:

      tmux ls

  Attach to the most recently used session:

      tmux attach

  Detach from the current session (inside a tmux session):

      Ctrl-B d

  Create a new window (inside a tmux session):

      Ctrl-B c

  Switch between sessions and windows (inside a tmux session):

      Ctrl-B w

  Kill a session by name:

      tmux kill-session -t name

Online-Cheatsheets mit cheat.sh

Mit cheat.sh gehen wir in die nächste Gewichtsklasse über, denn cheat.sh deckt so ziemlich alle Kommandozeilenbefehle, sowie Programmiersprachen, DBMSs, selbst Stackoverflow wird geparsed und inkludiert. Des weiteren ist cheat.sh nicht ein Sammelsumerium von Markdown-Dateien, sondern besitzt ein eigenes Backend, welches man wahlweise über den Browser, einen CLI-Client oder gar einer API mit curl abrufen kann.

Syntax

Einer der grossen Vorteile von cheat.sh ist, dass man keine Abhängigkeiten installieren und auch kein GUI wie einen Webbrowser haben muss, um es nutzen zu können. Wenn man beispielsweise per SSH remote auf einer Workstation unterwegs ist und gleich in der TTY kurz Informationen für ein gegebenes Problem einholen möchte, so geht das mit cheat.sh. Vorraussetzung ist, dass man curlinstalliert hat, was aber bei den meisten UNIX-Systemen wie MacOS und den meisten GNU/Linux-Distributionen wie Fedora oder Ubuntu sowieso der Fall ist.

Um Cheatsheets mit cheat.sh einzuholen, reicht ein curl-Aufruf gegen eine parametrisierbare Zieladresse. Das sieht dann so aus:

1
$ curl cht.sh/{topic}/{question}/{options}

Das topic ist dabei eine Programmiersprache wie Java oder Go, die Question eine mit “+"-Zeichen separierte semantische Fragestellung mit Stichwortcharakter (auch Query genannt) und Options eine Vielzahl von vordefinierten Parametern um das Suchresultat zu verfeinern.

Usage

Die Nutzung von cheat.sh ist durch den intuitiven Syntax auch hier deadsimple:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ curl cht.sh/curl
# curl
# Command-line tool for transferring data with URL syntax

# Process a single GET request, and show its output on stdout.
curl http://path.to.the/file

# Download a file and specify a new filename.
curl http://example.com/file.zip -o new_file.zip

...

Stellen wir uns vor, wir müssen schnell ein Array von Elementen in Go invertieren. Anstatt in einen Webbrowser zu switchen, tippe ich mit cheat.sh einfach einen curl-Befehl in mein Terminal des gerade offenens IDEs, sagen wir mal JetBrains GoLand, und bekomme sofort einen Output, welchen ich verwerten kann.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
$ curl cht.sh/go/reverse+a+list
/*
 * How do I reverse an array in Go?
 * 
 * Honestly this one is simple enough that I'd just write it out like
 * this:
 */

package main

import "fmt"

func main() {

    s := []int{5, 2, 6, 3, 1, 4}

    for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 {
        s[i], s[j] = s[j], s[i]
    }

    fmt.Println(s)
}

/*
 * http:play.golang.org/p/vkJg_D1yUb
 * 
 * (The other answers do a good job of explaining Interface and how to
 * use it; so I won't repeat that.)
 * 
 * [Brad Peabody] [so/q/19239449] [cc by-sa 3.0]
 */

Lerneinführungen mit cht.sh

Ein nützliche Option, die ich hier erwähnt haben sollte ist das :learn-Query-Atom. Das kann man als Parameter einem beliebigen Topic hinzufügen und so ein Crashkurs über das Zielthema bekommen. Versuchen wir uns mal an einem Learn-Element für die Rust-Programmiersprache (ich bin mir sicher der eine oder andere ist noch nicht ganz fit mit Rust 😉).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
$ curl cht.sh/rust/:learn
// This is a comment. Line comments look like this...
// and extend multiple lines like this.

/// Documentation comments look like this and support markdown notation.
/// # Examples
///
/// ```
/// let five = 5
/// ```

///////////////
// 1. Basics //
///////////////

#[allow(dead_code)]
// Functions
// `i32` is the type for 32-bit signed integers
fn add2(x: i32, y: i32) -> i32 {
    // Implicit return (no semicolon)
    x + y
}

#[allow(unused_variables)]
#[allow(unused_assignments)]
#[allow(dead_code)]
// Main function
fn main() {
    // Numbers //

    // Immutable bindings
    let x: i32 = 1;

    // Integer/float suffixes
    let y: i32 = 13i32;
    let f: f64 = 1.3f64;

    // Type inference
    // Most of the time, the Rust compiler can infer what type a variable is, so
    // you don’t have to write an explicit type annotation.
    // Throughout this tutorial, types are explicitly annotated in many places,
    // but only for demonstrative purposes. Type inference can handle this for
    // you most of the time.
    let implicit_x = 1;
    let implicit_f = 1.3;

    // Arithmetic
    let sum = x + y + 13;

    // Mutable variable
    let mut mutable = 1;
    mutable = 4;
    mutable += 2;

    // Strings //

    // String literals
    let x: &str = "hello world!";

    // Printing
    println!("{} {}", f, x); // 1.3 hello world

    // A `String` – a heap-allocated string
    let s: String = "hello world".to_string();

    // A string slice – an immutable view into another string
    // The string buffer can be statically allocated like in a string literal
    // or contained in another object (in this case, `s`)
    let s_slice: &str = &s;

    println!("{} {}", s, s_slice); // hello world hello world

    // Vectors/arrays //

    // A fixed-size array
    let four_ints: [i32; 4] = [1, 2, 3, 4];
...

Da geht schon einiges. Interessant, oder? Es gibt auch weitere Options wie :list, mit denen man alle möglichen Teilbereiche eines gegebenen Topics auflisten kann.

Installation (falls gewünscht)

Wie schon erwähnt, kann man cht.sh auch als Client installieren. Dafür gibt es einen nützlichen One-Liner:

1
$ curl -s https://cht.sh/:cht.sh | sudo tee /usr/local/bin/cht.sh && sudo chmod +x /usr/local/bin/cht.sh

Danach reicht ein cht.sh mit den entsprechenden Parametern. Es gibt neben dem Client auch noch die Weboberfläche unter https://cheat.sh/ , sowie Editor-Integrationen für die geläufigen IDEs und Texteditoren wie Vim, Emacs, VSCode oder gar JetBrains IntelliJ. Schaut euch am besten dafür die README-Seite auf dem GitHub-Repository von cheat.sh an.

Ultimative Cheatsheets mit navi

So, jetzt wissen wir’s, es gibt ganz unterschiedliche Arten von Cheatsheets. navi legt noch einen drauf und versucht alle Anforderungen, die man an einen CLI-Gehilfen haben kann, abzudecken. Genau wie Link’s (manchmal nervige) Hilfsfee aus der bekannten Nintendo-Videospielserie The Legend of Zelda, ist Navi da um in Situationen abhilfe zu schaffen, wenn man nicht genau weiss, wie der Kommandozeilenbefehl auszusehen hat. Von der alltäglichen Eingabe von Befehlen zum Erkenntnisgewinn bei der Ausführung von Bash-Scripten oder beim semantischen Aufruf von Launcher-Workflows wie beispielsweise mit Alfred, navi ist ein Alleskönner.

Installation von navi

Als MacOS-Nutzer nehme ich hier wieder brew zur Hand, um navi zu installieren. Weitere Pakete und Installationsmethoden sind auf der Github-Readme ersichtlich.

1
$ brew install navi

Nutzung von navi

Wie eingangs bereits gesagt macht navi mehr als nur die Ausgabe von Cheatsheets. Es ist sozusagen ein Tool, welches ein breites Spektrum von interaktiven Shell-Ausgangslagen abdeckt. Fangen wir aber mal mit den einfachen Use-Cases an. Zuerst lassen wir navi sich selber konfigurieren, mit einer interaktiven Willkommens-Prompt:

1
$ navi fn welcome

Tippt man sich durch die Willkommens-CLI, bekommt man ein paar Cheatsheets aus verschiedenen Quellen installiert und wird prompt in die erste Auflistung von Use-Cases geworfen.

Wenn man die Man-Page oder die --help-Flag zur Hand nimmt um Navi besser zu verstehen, kann man folgende Navi-Befehle mal ausführen.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
    navi                                         # default behavior
    navi fn welcome                              # show cheatsheets for navi itself
    navi --print                                 # doesn't execute the snippet
    navi --tldr docker                           # search for docker cheatsheets using tldr
    navi --cheatsh docker                        # search for docker cheatsheets using cheatsh
    navi --path '/some/dir:/other/dir'           # use .cheat files from custom paths
    navi --query git                             # filter results by "git"
    navi --query 'create db' --best-match        # autoselect the snippet that best matches a query
    db=my navi --query 'create db' --best-match  # same, but set the value for the <name> variable
    navi repo add denisidoro/cheats              # import cheats from a git repository
    eval "$(navi widget zsh)"                    # load the zsh widget
    navi --finder 'skim'                         # set skim as finder, instead of fzf
    navi --fzf-overrides '--with-nth 1,2'        # show only the comment and tag columns
    navi --fzf-overrides '--no-select-1'         # prevent autoselection in case of single line
    navi --fzf-overrides-var '--no-select-1'     # same, but for variable selection
    navi --fzf-overrides '--nth 1,2'             # only consider the first two columns for search
    navi --fzf-overrides '--no-exact'            # use looser search algorithm
    navi --tag-rules='git,!checkout'             # show non-checkout git snippets only

Am Anfang hatte ich gesagt, dass man Navi auch als Evaluationstool nutzen kann. Für das gibt’s die Möglichkeit, Navi als Shell-Widget zu provisionieren. Dafür müssen wir in unserer Shell der Wahl eine Zeile ins rc-File einfügen. In meinem Fall nutze ich die bekannte ZSH und muss in meiner ~/.zshrc diese Zeile irgendwo anhängen:

1
eval "$(navi widget zsh)"

Danach kann ich zur Eingabezeit in der Shell CTRL + g drücken, um die Navi-Prompt anzeigen zu lassen. Damit kann ich dann einfach mit Keywords semantisch danach suchen, was ich gerade mental nicht zur Hand habe.

Fazit 🙌

Es sei schonmal gesagt, dass es nicht nur diese 4 Cheatsheet-Tools gibt, sondern eine Vielzahl mehr. Eines ist aber klar, Cheatsheets werden in Zukunft immer wichtiger. Bei der zunehmenden Anzahl von Technologien und ewigs steigender Abstraktion von Komplexitäten. Im Tech-Umfeld ist die Fähigkeit der Aneinungung und Auffindung von Lösungen und Antworten genau so wichtig wie die erlernten Skills, die man täglich einzusetzen hat. Man kann nicht immer alles wissen, aber man muss die Fähigkeit haben, so schnell wie möglich an dieses fehlende Wissen zu erlangen. Cheatsheets sind hierfür quasi unerlässlich.

Mein Daily Driver ist definitv eine Kombination aus tldr und cht.sh. Mit tldr kann ich schnell den gewünschten Flag oder einen Beispielbefehl finden, welcher mir einfach nie in den Kopf will, ganz egal wie oft ich diesen über die Jahre schon genutzt habe. Für die komplexeren Fragestellungen ist cht.sh einfach der Hammer und liefert stets sinnvolle und nutzbare Ergebnisse, sodass ich nicht mehr darauf verzichten möchte.

Ich hoffe, dir diese Tools etwas nähergebracht zu haben. Probier’s einfach mal aus und bleib gespannt auf weitere TechUp’s!

https://github.com/srsudar/eg

https://github.com/tldr-pages/tldr

https://github.com/chubin/cheat.sh

https://github.com/denisidoro/navi