efficient terminal tools
In this post, I hope to give the best, most useful, and most practical terminal-based tools that I regularly use. These are the tools I wish someone had forced me to try years ago, so I hope to convince you to try them here.
This post was originally written for a presentation I gave to coworkers. I plan to update it over time with any new discoveries I make.
- prerequisite: you need a good tty
- cht.sh
- gh-copilot
- ripgrep and fd
- gh
- atuin
- lazygit and lazydocker
- vim
- nushell
- Honorable Mentions
As I progressed in my education and experience as a software engineer, I received a lot of guidance as to how to improve how my software was structured. However, I was never really instructed on the process of creating that software. I moved between Eclipse, JetBrains, and VS Code without ever really learning how to navigate a codebase quickly, script programs together, or work with git
beyond the dreaded:
git add . && git commit -m "changes" && git push
Later, I saw online what certain engineers and bash wizards were capable of. Certain things feel intractable—like mastering every awk
and bash
nuance. However, as I used the tools, I got more comfortable and began to move faster.
Additionally, there’s been an influx of usability improvements. As developer interest grows in languages like Rust and Zig, the chance to redesign from scratch has led to a new wave of excellent, easy-to-use tools.
prerequisite: you need a good tty #
I will cry if you run these in Command Prompt.
Terminal applications can only do so much if the surrounding terminal interface is poor.
For Linux and Mac, I highly recommend either kitty or ghostty. Both have excellent performance and support all the fancy terminal features. Namely, they work with the kitty terminal graphics protocol that lets you display images in the terminal!
For Windows, alacritty is the best native option I have found. Not quite as feature-rich in my experience, but the only tty of this class that is windows-native (that I have found).
Also important: Install a Nerd Font! Many programs depend on these for icons.
cht.sh #
When the maze of arguments and options are starting to slow you down, cht.sh is your best friend. At any terminal with internet access, you can use it to search for command-line tools and their usage.
Lets say you are trying to do a simple tar operation.
First, you can use it directly from your browser or through curl: curl cht.sh/tar
Or, you can install their command line client. I prefer this, as you don’t need to use URL syntax to search. I’ll run cht.sh tar
:
cheat:tar --- tags: [ compression ] --- # To extract an uncompressed archive: tar -xvf /path/to/foo.tar # To extract a .tar in specified directory: tar -xvf /path/to/foo.tar -C /path/to/destination/ # To create an uncompressed archive: tar -cvf /path/to/foo.tar /path/to/foo/ ... tldr:tar # tar # Archiving utility. # Often combined with a compression method, such as gzip or bzip2. # More information: <https://www.gnu.org/software/tar>. # [c]reate an archive and write it to a [f]ile: tar cf path/to/target.tar path/to/file1 path/to/file2 ... # [c]reate a g[z]ipped archive and write it to a [f]ile: tar czf path/to/target.tar.gz path/to/file1 path/to/file2 ... ...
gh-copilot #
For the more complicated tasks, or for when you’re not even sure which command you need, I will often reach for the gh-copilot extension for gh
.
I have this aliased to ??
in my terminal so I can quickly search for commands. I find this to be a lot more ergonomic than switching to something like Warp Terminal when I need to search how to use a single command. 1
ripgrep and fd #
When I speak of older tools getting a modern redesign, these are probably the prime examples.
fd and ripgrep are fantastic alternatives to find
and grep
, and are multithreaded by default. 2 They have become my default for scripting operations to find certain regex patterns and file names quickly.
gh #
This section is basically here to say: stop trying to script GitHub with curl
!
gh provides a helpful wrapper over many GitHub APIs and git
operations. This integration allows for commands like gh repo clone bizmythy/nixconf
, which clones based on the GitHub repo name using your preference setting for SSH/HTTP. It also lets you make queries like gh repo list --visibility=public
:
NAME DESCRIPTION INFO UPDATED
bizmythy/nixconf Nix Configuration Files public about 1 hour ago
bizmythy/bizmythy.gi... public about 2 hours ago
bizmythy/nixpkgs Nix Packages collect... public, fork about 19 hours ago
bizmythy/typeracer-FPGA public, archived about 4 days ago
bizmythy/hugo The world’s fastest ... public, fork about 4 days ago
bizmythy/zed configuration for ze... public about 5 days ago
...
gh
can output as json
, which can be used in scripting quite easily.
atuin #
One of the most aggravating thing about working in the terminal can be when you know you have run a command before but it can’t be found in your history. Maybe it was in another session, maybe your history ran out of space, or maybe it was run on a completely different machine.
atuin is a terminal history manager that aims to always capture the history of the commands you run. This means syncing across sessions, windows, different terminals, and even different devices if you choose.
It stores all of your command history in a local SQLite database and replaces your CTRL+R
search with a fuzzyfind of that history database in a nice TUI.
lazygit and lazydocker #
lazygit
and lazydocker
are wonderful TUIs for git
and docker
respectively by @jesseduffield.
In both, the keybinds are nicely displayed for you at the bottom, but you can even use your mouse.
Both have almost entirely replaced most of the docker
and git
calls I would type out before. lazygit
especially has completely changed how I work with git, as it allows for quickly selecting files to add, exclude, and discard from your working git
changes to your commit.
vim #
I don’t mean to beat a dead horse, but I truly don’t understand why vi-style keybindings are not the industry standard.
I’m not adamant that you use full-fledged vim
itself. VS Code has VSCodeVim, which works great most of the time. I use zed for my development, which has an extremely robust vim mode. Even emacs
has “evil” mode.
Regardless, I highly recommend taking a week, or even a weekend, to just give the keybinds a try in your favorite editor. Once you summit the initial learning curve, you will really see the benefits. I was a doubter myself at first, but after trying it, I haven’t looked back.
nushell #
Nushell is my absolute favorite of these tools.
It is probably wrong to even call it a tool, as nu
is a fully-fledged shell which can be in lieu of bash
/zsh
/fish
. 3 The key feature that sets nu
apart from these is Pipelines.
Pipelines are a lot like traditional piping of stdin to stdout, but in nu
they can store structured data. These look a lot like json
and are printed as nicely formatted tables. You can then leverage the nu
language functional operators to do some fairly powerful things:
Here’s a nu
script to get the Git-LFS files in a repo and sort by the ones using the most space.
#!/usr/bin/env nu
let lfs_file_data = (
git lfs ls-files --size |
detect columns -n |
reject column1 |
rename hash file size |
update size {|row| $row.size | str substring 1..-2 | into filesize} |
sort-by size
)
print $lfs_file_data
let total_size = ($lfs_file_data | get size | math sum)
print $"Total size: ($total_size)"
Here’s what the script output looks like:
╭─────┬────────────┬────────────────────────┬──────────╮ │ # │ hash │ file │ size │ ├─────┼────────────┼────────────────────────┼──────────┤ │ n │ 3wfaijoefw │ ... │ 8.1 MB │ │ 334 │ 7e193593ce │ smallfile.txt │ 8.1 MB │ │ 335 │ 73a43c7901 │ lessbigfile.png │ 20.0 MB │ │ 336 │ b57b275ee0 │ bigfile.mp4 │ 65.0 MB │ ├─────┼────────────┼────────────────────────┼──────────┤ │ # │ hash │ file │ size │ ╰─────┴────────────┴────────────────────────┴──────────╯ Total size: 143.9 MB
The nice things here:
git lfs
commands don’t have the ability to outputjson
, but you can just pipe them intodetect columns
and it will figure the data structure out for you!- There is a first-class
filesize
datatype, which we convert a string to and sort by. I don’t even want to know the crazy scripting it would take to properly compare megabits with kilobytes without this. - The biggest selling point for me: I didn’t have to look up anything. No googling. No reading manpages.
nu
has a very high skill floor, and it can become very powerful if you take the time to read through the excellent Nushell Book.
Honorable Mentions #
These tools are more niche, but come in handy for specific tasks.
I have never had a good experience going to shady file type conversion websites. They are always slow, covered in ads, and usually don’t work.
For converting, cropping, editing, and re-encoding videos, use ffmpeg. For images, use imagemagick.
This isn’t a terminal tool, but for PDF arranging, try pdfarranger.
If you are working with docker images, dive is a great tool for inspecting and analyzing docker images. It has often highlighted issues I could not find with any other image analysis tool.
bat
is just cat
with syntax highlighting. I use it all the time, especially because it behaves exactly like cat
if it detects it is being piped into another command.
Warp Terminal is pretty cool, but it lacks a lot of the rendering features I have come to expect from my TTY and can have some compatibility issues with some TUI applications. ↩︎
A capable user of GNU Parallel can make
grep
andfind
operations parallelized, which is useful in scripting. However, for most use cases, having these optimizations compiled in is very beneficial. ↩︎Similar to
fish
,nu
is extremely not POSIX compliant, so copy-pasting or running scripts withnu
as the interpreter are bound to fail often.Never set a non-POSIX shell as your system’s default shell. I set
nu
as the default program that launches when I start my TTY. ↩︎