Memorize less, know more with state-of-the-art cheatsheets!

21.09.2022β€’Raffael Schneider
Tech Rust CLI Productivity

Who doesn’t know the problem? You’re currently screensharing with a technical stakeholder and trying to quickly execute another command in the command line to get the desired information. You only remember the command signature, but the parameters that follow are no longer present off the top of your head, awkwardly typing the tab key in hopes that autocomplete will automatically complete the missing flags, but nothing useful comes out of it. Unfortunately, the --help flag is only implemented half-heartedly, so next you call up the manpage of the command with man and try to find the corresponding entry with the desired flags using the search function. In vain… Finally, after switching to the web browser using a key combination and a quick Google search on Stackoverflow, you find yourself scrolling through a multitude of answers. 🫠

Of course, one then finds the solution to the actual initial problem, which is satisfying. But it won’t be long until you’ll need to use the next slightly more specialized CLI-command, and the whole process starts again from the beginning. Unless you use these commands on a daily basis, you realize that you might have some catching up to do. But is this effort really worth it? Not necessarily, if you have cheatsheets!

Such time-critical situations don’t only come up in the command line, they also lead to awkward self-consciousness when actively programming or trying to use a shortcut in a GUI of your choice, which often gnaws at your own perception of competence.

To be clear; such moments are not necessarily due to one’s own lack of competence, but are merely a daily expression of the rapidly advancing development of the tech stack, which we developers and IT enthusiasts always have to master anew when new components, tools or technologies are added. So don’t be discouraged if the previous description of a possible scenario has already caused you frustration, but take it as a sign that you can improve something here, to ensure a more efficient and transparent workflow and ultimately save time. This is exactly what brings us to the core topic of today’s TechUp, namely how modern cheatsheets can be used to optimize your workflow and be able to better focus on the problem to be solved, and thus also how you can be able to avoid spending time on learning about an archaic parameter flag of a CLI tool, which you only use once a month anyway.

Figure: Could you do it?

Know more with cheat sheets πŸ—’πŸ˜Ž

Cheatsheets could be, for example, Post-Its that stick to the bottom edge of your monitor and help your remember frequently used processes in the form of short keywords. Thus, looking at the post-it becomes a tool that makes your own workflow a few seconds faster and more efficient. Of course, such cheatsheets can also be used digitally and are commonly used in IT.

While tech-focused cheatsheets are nothing new, they have increased tremendously in flexibility and possibilities in recent years, and have become indispensable in a modern workflow. Here’s where I’d like to make a distinction and divide the different categories of cheatsheets as follows:

  • UNIX/Linux commands and CLI tools: These cheatsheets are a user-focused collection of common usage examples of command line commands, which often include placeholder elements. These can be further refined with keywords, so pretty much all use cases of a given CLI tool can be displayed.
  • GUI and Shortcuts: These cheatsheets are visual in nature and show a preselected searchable collection of shortcuts and GUI processes that can be used to operate the desired GUI. These are definitely useful, but are not the main focus of today’s TechUp.
  • Programming languages and idiomatic programming patterns: These cheatsheets depend on the programming language and aim to show common functions, code snippets or even patterns.
  • General IT topics by using knowledge markets and Q&A platforms: These cheatsheets use an API for common Q&A platforms such as Stackoverflow or Serverfault and look for the most relevant answer straight away. These can be tailored to the command line or programming in general, but often also include other tangential IT topics. The maintenance of such knowledge databases is complex, but these tools are quite usable in their current version and often quite helpful.

So, before we get started with the actual cheatsheets, I would like to mention that the different tools that I present here access different knowledge bases, and there can often be multiple clients for a given knowledge base. In this TechUp I’ll try to give an overview of the most important sources and the corresponding relevant clients. πŸ˜„

Coreutils cheat sheet with eg

eg is a relatively simple cheatsheet written in Python which provides cheatsheets for the UNIX coreutils like cp or strace. The knowledge base is installed as part of the installation and is basically a collection of Markdown files. This collection can be viewed on the GitHub repository.

Installing eg

eg can be installed via Python package manager pip or for MacOS with brew. Here we take the brew-based installation path:

1
$ brew install eg-examples

Use of eg

The use of eg is “deadsimple”:

1
$ eg <program>

You can also create your own Markdown files to extend the set of searchable terms. What speaks for the use of eg is definitely its simplicity and clarity. A small but nice cheatsheet for the occasional UNIX user.

 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 with tldr

The next step up from eg is tldr. tldr, or more accurately called tldr-pages, is a Git-based collection of short but helpful man-pages for all common command-line utilities. tldr thus covers not only the coreutils like eg, but pretty much all cli commands imaginable. Furthermore, tldr is internationalized and offers cheatsheets not only in English but also in languages like German, French or Spanish.

Installation of `tldr

To use tldr, we need a client that is able to read the pages from Github. There’s either a Node.js-based client, which can be installed with npm install -g tldr, or a Python-based client, which can be installed with pip3 install tldr. But here I decide to use a Rust-based binary as client, which is called tealdeer:

1
$ cargo install tealdeer

Use of tldr

Tealdeer as a client can locally cache the tldr-pages from the GitHub repository. Thus, the performance after a successful update is much faster than with alternative clients. You can simply force this with tldr --update.

Using tealdeer/tldr is just like 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

This example is deliberately a macOS-specific representation to show that archaic commands are also covered. tldr-pages contain not only pure examples of command line commands, but also show helpful shortcuts. Here is an example with 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 with cheat.sh

With cheat.sh, we move to the next level. cheat.sh covers pretty much all cli commands, as well as programming languages, DBMSs, and even Stackoverflow is parsed and included. Furthermore, cheat.sh is not a collection of Markdown files, but has its own backend, which can be accessed either through the browser, a CLI client or even an API with curl.

Syntax

One of the big advantages of cheat.sh is that you don’t need to install any dependencies or have a GUI like a web browser to use it. For example, if you are using SSH remotely on a workstation and want to get some information for a given problem right in the TTY, you can do that with cheat.sh. The prerequisite is that you have curl installed, but this is the case with most UNIX systems like MacOS and most GNU/Linux distributions like Fedora or Ubuntu anyway.

To get cheatsheets with cheat.sh, a curl call against a parameterizable target address is sufficient:

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

The topic is a programming language such as Java or Go, the question a semantic question with keyword character separated by “+” signs (also called query), and the options are a variety of predefined parameters to refine the search result.

Usage

The use of cheat.sh is - how should it be different - deadsimple due to the intuitive syntax:

 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

...

Let’s imagine we need to quickly invert an array of elements in Go. Instead of switching to a web browser, I simply type a curl command with cheat.sh into my terminal of the currently open IDE, let’s say JetBrain’s GoLand, and immediately get an output that I can use.

 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]
 */

Introductions with cht.sh

A useful option I should mention here is the :learn query atom. You can add this as a parameter to any topic and get a crash course about the target topic. Let’s try a learn element for the Rust programming language (I’m sure one or the other is not quite proficient in Rust yet πŸ˜‰).

 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];
...

There’s a lot going on. Interesting, right? There are also other options like :list which can be used to list all possible subsections of a given topic.

Installation (if needed)

As already mentioned, cht.sh can also be installed as a client. There’s a useful one-liner for that:

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

Now, a cht.sh with the appropriate parameters is sufficient. In addition to the client, there is also a web interface at https://cheat.sh/, as well as editor integrations for the common IDEs and text editors such as Vim, Emacs, VSCode or even JetBrains IntelliJ. Check out the README page on cheat.sh’s GitHub-Repository.

Ultimate cheat sheets with navi

So now we know that there are many different types of cheat sheets. navi goes one step further and tries to cover all the requirements one could have for a CLI helper-tool. Just like Link’s (sometimes annoying) helper fairy from the well-known Nintendo video game series The Legend of Zelda, Navi is there to help in situations where you don’t know exactly how Command line command has to look like. From everyday commands to gaining insight when running bash scripts or semantically invoking launcher workflows such as with Alfred, navi is a jack of all trades.

Installing navi

As a MacOS user, I use brew again to install navi. Other packages and installation methods can be found on the Github-Readme.

1
$ brew install navi

Use of navi

As already mentioned, navi does more than just outputting cheatsheets. It’s a tool that covers a wide range of interactive shell starting points. But let’s start with the simple use cases. First, let’s configure navi itself, with an interactive welcome prompt:

1
$ navi fn welcome

If you type through the welcome CLI, a couple of cheatsheets from various sources will be installed and you’ll promptly be shown the first list of use cases.

If you consult the man page or the --help flag to understand Navi better, you can run the following Navi commands.

 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

At the beginning, I said that Navi can also be used as an evaluation tool. There’s the option of provisioning Navi as a shell widget. To do this, we have to add a line to the .rc file in our shell of choice. In my case I use the well-known ZSH and have to append this line somewhere in my ~/.zshrc:

1
eval "$(navi widget zsh)"

After that, I can press CTRL + g in the shell at input time to bring up the navi prompt. I can then simply use keywords to search semantically for what I don’t have mentally at hand at the moment.

Conclusion πŸ™Œ

It should be said that there are not only these 4 cheatsheet tools, but a lot more. One thing is clear though, cheatsheets will become more and more important in the future, with the increasing number of technologies and eternally increasing abstraction of complexities. In the tech environment, the ability to think and find solutions and answers is just as important as the learned skills you have to use every day. You can’t know everything all the time, but you must have the ability to get to that missing knowledge as quickly as possible. Cheatsheets are virtually indispensable for this.

My daily driver is definitely a combination of tldr and cht.sh. With tldr I can quickly find the flag I want or an example command that I just can’t get my head around, no matter how many times I’ve used it over the years. For the more complex questions, cht.sh is simply awesome and always delivers meaningful and usable results, so I wouldn’t want to do without it.

I hope I’ve been able to bring these tools a little closer to you. Just give it a try and stay tuned for more TechUps! πŸš€

https://github.com/srsudar/eg

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

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

https://github.com/denisidoro/navi