Skip to content

CLI++: Upgrade Your Command Line With a New Generation of Everyday Tools

In a recent email, KDABian Leon Matthes highlighted some of his go-to command line tools for everyday use on Unix. His recommendations sparked a lively exchange among our colleagues, each sharing

their own favorite utilities.

Many of these tools offer efficient alternatives to standard Unix programs, speeding up the workflow or otherwise enriching the development experience.

This article aims to serve as a resource for the wider community, encouraging others to explore these tools and upgrade their command line setup for improved productivity.

The following common Unix tools are listed in this document, with their alternatives specified in their respective sections:

Additionally, there are some tools here that do not replace common programs, but are extremely useful when working in a shell environment. These are broken into two broad categories:

Many of these tools can be considered examples of the “rewrite it in Rust” approach (RIIR), which in this document will be denoted with Ferris the crab: 🦀

Finally, there is a bonus Rust crate listed at the end that is helpful for writing CLI programs of your own.

Note: for scripting, stick with standard Unix tools, as they’re more widely distributed and will work in most other Unix environments. The tools in this article are meant to improve quality of life working within your own shell environment on a daily basis.


cd


Python

autojump is an alternative to cd, invoked with the command j. It jumps to what it determines to be the best fit for whatever directory name you give it. For example, j cxx-qt will change directory to the cxx-qt directory, even if it’s nested several levels deep from the current working directory.

If autojump doesn’t prioritize a directory correctly, its priority weight can be increased or decreased. j -i XXX will increase the priority weight of the current working directory by XXX, while j -d XXX will do the opposite and decrease the weight accordingly.

autojump also supports opening a file browser at a matched location rather than cd‘ing into it, by invoking jo rather than j.

Unfortunately, autojump has not been in active development for the past two years, and can break in some environments. The next tool, zoxide, will be more reliable if autojump breaks for you.

Rust

zoxide is a similar program to autojump, actually drawing inspiration from it. Invoked with the command z, it remembers paths that have been visited in the past and matches the best fitting directory. The tool also supports interactive selection of the correct match via the zi command, which uses the tool fzf for fuzzy finding. fzf is listed later in this article.

zoxide can also be used the same way as plain cd, and can target absolute and relative paths. It can be configured to be invoked from the j and ji commands, or even cd to fully replace the cd command.

Finally, it is implemented in Rust, resulting in better performance than autojump.


ls


Rust

lsd is a more feature-rich version of ls, including colors, icons, tree-view, additional formatting, and more. It is also highly configurable through a yaml config file.

Rust

eza is a small, fast ls rewrite that knows about symlinks, extended attributes, and git, and has support for hyperlinks. Similar to lsd, it supports colors and icons, which are configurable with a yaml config file.


man


This project has several clients written in different languages. The most mature client is an npm package.

tldr is an alternative to using man for most common use cases. It is a collection of pages that provides brief descriptions and usage examples for loads of programs, standard Unix and otherwise. It’s much faster if you don’t need to read about every option in detail in order to find the correct way to invoke a command or select the proper option quickly.

For example, if the man page for tar is too long to read when looking for the right option to do something, simply running tldr tar will show a list of examples that will usually have the options you need.

Python

cheat.sh and its associated shellscript cht.sh, provide access to a superpowered aggregation of cheatsheets for programming languages and CLI tools, including tldr pages and other sources.

It has a great system for querying cheatsheets, and you don’t even need to install a tool (though you can), as the query response can be retrieved by curl. It’s also usable inside editors, for easy referencing while programming.

The cheatsheet sources also include StackOverflow answers, which allow for flexible usage like so:

$ cht.sh js parse json

A nice way to use cheat.sh without installing anything is to put the following function in your .bashrc or .zshrc:

function cheat() {
    if ! curl -s "cheat.sh/${*//\ /+}"; then
        echo "Failed to get the cheatsheet" >&2
        return 1
    fi
}

Then you can use it like

$ cheat tar

or

$ cheat cpp number to string

find


Rust

fd is an alternative for many use cases of find.

While it is not as powerful as find, it is designed to be faster and more user-friendly for the majority of find‘s use cases.

No more find -name .rs — just use fd .rs and you’re good to go.

fd is super fast and will search through your entire filesystem in a matter of seconds (Leon recorded 1.4s on his machine with 177GB of files).

By default, fd will not include any hidden files that are ignored by .gitignore, which is very useful as it doesn’t give you any random junk in your build directory and speeds up the search even further.

Use --hidden and --no-ignore (or -H and -I, respectively) to search for everything.

fzf

Go

fzf is a fuzzy-finder that can match files, command history, processes, hostnames, bookmarks, git commits, and more, with interactive selection. It’s also usable as a vim or neovim plugin.


grep


Rust

ripgrep (rg as a command) provides an incredibly fast grep alternative with a simpler interface.

Did you ever have to wait for grep to finish searching a directory or had to look up the right options for specific usage? Well, no more! Ripgrep will search the contents of large build directories within milliseconds.

Just running rg Q_PROPERTY will search through the entire current directory if you don’t pipe something into it, which is very convenient and the way it should have been in the first place. The output is also a lot friendlier and easier to read.

Like fd, use --hidden and --no-ignore to search in hidden and ignored directories/files.


cat


Rust

bat, written by the creator of fd, is a superpowered Rust rewrite of cat. It provides syntax highlighting, line numbers, support for displaying non-printable characters, support for showing multiple files at once, and pipes to less by default for large output. It can also be integrated with fzf, find, fd, ripgrep (rg), git show, git diff, man, and more. A tool you’ll read about later in this document, delta, uses bat as a dependency to display diffs.


diff / git diff


Perl

diff-so-fancy is an alternative to vanilla git diff that improves readability, with better formatting, colors, and highlighting. Configure git to use diffsofancy as its pager, and git diff will provide the more readable diffsofancy output.

Rust

delta is an alternative to diffsofancy that’s written in Rust. It includes additional features, like line numbers, syntax highlighting, side-by-side, improved navigation between files in large diffs, hyperlinked commit hashes, improvements for display of git blame and merge conflicts, and the ability to syntax-highlight grep output. delta uses bat under the hood and, as such, they can share color themes.


prompts & shells


Rust

starship is a prompt written in Rust, which can be used with a number of popular shells including bash, zsh, fish, and even Windows shells like cmd and PowerShell.

The prompt is both stylish and informative, providing information like git branch, versioning, and more in the prompt itself. It also indicates the time length of command execution, whenever the run lasts for more than a few seconds — very helpful for gauging the duration of a build. This prompt should be utilized with a NerdFont for icon support.

Starship is also extremely configurable, so any details can be omitted or added; the look and feel of the prompt can be completely customized, etc.

zsh prompts & plugins

zsh

Some shell users argue that switching from bash is definitely worthwhile, with zsh being the favorite choice for many. It’s highly configurable and has a rich plugin ecosystem.

oh-my-zsh is a zsh framework that makes completions, searching in history, the prompt, etc., much nicer than the defaults. It can, of course, be tweaked much further from there. If you find oh-my-zsh to be a bit bloated, there are more lightweight alternatives such as ZimFW or Zinit.

Some zsh plugins can also serve as alternatives to previously mentioned tools. There are quite a few useful plugins listed here (they should work with any plugin manager): https://github.com/unixorn/awesome-zsh-plugins.

Some that stand out include:

  • zsh-vi-mode
    • a proper Vim mode for the terminal, much better than the default one
  • fast-syntax-highlighting
    • nice while-you-type syntax highlighting in the shell
  • fzf-marks
    • alternative workflow to zoxide and similar cd improvements
    • this can also be used with bash
  • zsh-autoenv
    • customize environment variables by directory, similar to the tool direnv mentioned later

Note: If you are interested in switching away from bash but don’t like zsh, consider trying fish.


Update Systems


Rust

topgrade is a tool which conveniently updates several package managers with one command.

Just run topgrade and every package manager under the sun will be updated, one after the other. This even includes flatpaks and updates to your systems package manager, very convenient.


Misc.


Go

direnv is an extension for several common Unix shells, focused on environment management. More specifically, it is intended to unclutter .profile and export different environment variables depending on the current directory.

On each prompt, it checks for the existence of a .envrc file in the current directory, otherwise looking for .env, and loads or unloads environment variables accordingly. It’s a single executable and very fast.

direnv is also extensible with bash files in .config.

C++

blobdrop enables drag-n-drop of files from a terminal window, which can be very convenient when using the command line as a file browser. It was written by fellow kdabian Magnus Gross.


bonus!


Rust

bonus is not quite a tool, but a Rust crate used frequently for writing CLI tools, called clap.

clap is used in the codebases of a majority of the Rust tools in this document, as it’s incredibly useful. It’s the reason most Rust CLI tools have great UX.

Using the derive feature, you can simply mark up a struct of data you need from your command line arguments and clap will generate a beautiful and convenient CLI interface for you. Just take a look at the derive documentation to get an idea of what this looks like.


Other Tools


We hope these tools can improve your workflow, as they certainly make our lives on the command line far more enjoyable.

If you have any additions to this list, feel free to discuss them in the comments.

About KDAB

If you like this article and want to read similar material, consider subscribing via our RSS feed.

Subscribe to KDAB TV for similar informative short video content.

KDAB provides market leading software consulting and development services and training in Qt, C++ and 3D/OpenGL. Contact us.

Categories: Featured / KDAB Blogs / Rust / Technical / Tooling

Tags: / /

2 thoughts on “CLI++: Upgrade Your Command Line”

  1. Good overview! This list covers most of the tools I use on a regular basis.

    Here are a few more TUI tools:
    * ncdu, as regular du is way too slow, especially on network drives (recent ncdu versions can run with multiple threads). Written in Zig.
    * yazi, a terminal file manager (Rust). I used to use ranger (Python), but yazi is much faster, and has better out of the box support for image previews.
    * batman, a shell script to combine bat and man. Supports fzf for searching man pages, and syntax highlighting for man pages. You may have alluded to it when mentioning bat.

    Some that I don’t use often but that I know about:
    * btop is like htop but even more customizable
    * lazygit is a recent addition to my list, it seems quite useful for browsing git history, interactive rebases, replacing add -p, etc.

    Something I am really missing in a company setting with petabytes of data and very complex folder structures is a shell history feature that remembers the directory a command was ran in, so that it may be found later. Being able to expand a history entry `cd ../subdir` to `cd /very/very/long/path/to/a/deep/folder/hierarchy/subdir` would be nice. I’ll look into the alternatives cd tools, but my point still stands for other commands, such as cp, etc. Any suggestions?

    1. Hi @MayeulC,
      thank you for sharing your own suggestions.

      Regarding the working directory in the history, I know that fish-shell prioritizes commands that were run in the cwd when suggesting commands from the history. Though I think that is not quite what you’re looking for.

      After a bit of googling, it seems that fish unfortunately doesn’t store the cwd itself (see: https://github.com/fish-shell/fish-shell/issues/120 ).
      However, a comment on that issue suggests Atuin ( https://github.com/atuinsh/atuin ), which does store the cwd per command. So that should be able to do what you want.
      Note that I have not used Atuin yet. I would be interested in how well it works, please let me know if you try it.

      Kind Regards,
      Leon

Leave a Reply

Your email address will not be published. Required fields are marked *