251 comments

[ 5.0 ms ] story [ 274 ms ] thread
I wrote dug, a cli tool I made to help visualize DNS propagation but is a great learning tool. Didnt make this list though sadly.

https://github.com/unfrl/dug

https://dug.unfrl.com

Seems your tweet was posted about the time the post was made? dug looks like it will be very useful, thank you
.. in fact I’ve just realised it will help me with an issue and I will be using it tomorrow!
Happy to hear it can help you!
direnv is such a godsend that I shill for it on every team and in every company now, it's such a great tool.
direnv should have been part of unix/linux/posix environments from the start. Whenever something's install steps tell you "go add this export statement to your .bashrc" or similar, it never sat well. That sort of thing should be scoped by path, and shell independent -- exactly the thing direnv enables.
The first thing I did recently in some cleanup work for a team was set up direnv and have it auto-switch kubernetes context by location.
I was reading the thread and thinking "this is a cool tool, might use someday".

>have it auto-switch kubernetes context by location

Now I'm sold, thanks!

I never understood why people were so enamored with direnv, but this makes me understand it a bit. I don't think I need it right now, but I'll keep it in mind for this use case.
I alias ~~ to load .env if it exists, and unload the custom pieces if it doesn’t. I’ve seen people do that with :: as well.
(comment deleted)
100% agree. It's such a versatile tool -- for example I have the following:

    git config --local core.hooksPath $PWD/.githooks
    export DOCKER_CONFIG=$(realpath secrets/docker)
Combine that with git-crypt[0] (obviously, don't commit secrets in plaintext to your repo!) for example and you have some really nice ergonomics.

Not enough people know about direnv.

[0]: https://www.agwa.name/projects/git-crypt/

Could not agree more. I've shilled it three times in the past week alone. And I've also taken to mentioning it in any README involving env vars. Awesome tool.
I read through the direnv docs, but I'm trying to think of how I'd use it. Can you or anyone else give me some examples? Even just listing which directories you have .env or .envrc files in, and what environment variables you use in them.
The approach of using direnv and putting .env files in directories encouraged me to pull more variables from other places in config files, or shell scripts, or global variables in a programming project, and put them in environment variables instead. It's very aligned with the 12 factor philosophy [1].

Also, many scripts start by just defining a bunch of variables -- and many of those, in terms of other variables. Say, a PROJECT_ROOT directory, and a PROJECT_DOCS directory defined relative to that, etc. Then, a bunch of command parsing logic, after defining all those default values, so the user can set values of their own. Then, finally, the script can start doing the thing it was put there for in the first place.

With the .envrc approach, some of that stuff is pulled out of the script (making it shorter and simpler) and considered part of the directory environment.

  [1] https://12factor.net/config
My biggest use is for configuring database connections. Create something like `FOODATABASE=postgres://user:password@server:port/name` and then whenever I am inside the project, I source the FOODATABASE environment variable wherever it is needed. Another convenience pattern I use with Django is to have a PROJECT_IS_DEBUG key -iff variable is defined, enable extra tracing functionality without requiring any development specific configuration files.

Example server pattern to default to production:

  if "PROJECT_IS_DEBUG" in os.environ:
    DEBUG = True
    ALLOWED_HOSTS = ["*"]
  else:
    # production configuration by default
All for a one-time configuration setup. A further boon of this workflow is that systemd natively supports an EnvironmentFile configuration, so you can re-use the same configuration format from development to production.
Projects I work on wind up with a bin/ directory containing any number of little helper scripts and tools. With direnv that dir can automatically be first in your PATH when you're in the project, but not on it at all when you're elsewhere. Ditto for, say, putting a Python project's virtualenv/bin folder on PATH or a NodeJS project's node_modules/.bin.

Projects I'm on also tend to wind up with an etc/ directory that configures things like PATH and tab completions for a good baseline experience - think of it as standardizing and isolating the snippets many projects tell you to put in your ~/.bashrc to work on the project.

Direnv makes it easy to automatically load those, too.

It really did revolutionize the way I work, by making it trivial to make projects much more self-contained, the way I'd always wanted them to be but hadn't been quite sure how to achieve.

I've only used Nix for managing my personal installed package on OS X so far, but I believe direnv works really well in tandem with Nix - use a Nix file to define your project's dependencies and use direnv to automatically activate all those dependencies whenever you're in the project's directory.

I place a .envrc at the root of our monorepo with a handful of env vars that configure stuff like PATH (to point to the various scripts, tools, and executables that are used in the dev environment), override the sane default config files with an environment variable (extremely useful when chasing down specific bugs) and to redirect or control logging and debug info when running tools and systems.

It makes it a breeze to pull in a commit and set up a development harness that pokes at whatever thing I need to poke at in my local environment. And it does it without changing a line of code or command line invocation, which is a big deal in polyglot environments with various build constraints (not passing -DFLAG=thing is enormous in a big C/C++ code base, for example).

Even just being able to point whether a service is looking at a dev/production/local service/database is a big deal if you've invested in IaC and don't want to mess with any config files to do your work (as .envrc is probably in your .gitignore).

A very nice use of direnv is automatically calling virtualenv's `activate` on directory entry, so you don't need to do that yourself.
When I was working with google cloud it would have been nice to have gcloud change project depending on the folder I was in.

Kind of imagine if git didn't change repo when you switched directory, that was how it felt.

I've actually moved from direnv to shadowenv[1]. It's more powerful since it's using a Lisp dialect called Shadowlisp that lets you easily do things like append/prepend to $PATH, expand paths and other common actions.

[1] https://shopify.github.io/shadowenv/

As a maintainer, I hoped to see Hurl [1], a tool for testing HTTP with plain text and curl, but alas it isn’t here!

[1] https://hurl.dev

This doesn't quite appear to be the type of tool that fits the theme of the list (coreutil replacements).
It could fit here nevertheless?

« new inventions

Here are some tools that are not exactly replacements for standard tools:»

Oh it runs stuff like curl. I use html2text just about 5 times a day, and want better ways of working with html _as_ text without a browser of an kind.
Couple ones there that I’m keen to try out. bat in particular seems like such an easy win
I use both bat and cat often. cat normally, but bat for source code since it comes with syntax highlighting and line numbers by default.
fd and ripgrep are the ones that have really stuck with me, replacing find and grep in my finger memory.
You can of course alias these commands as I have done, although coworkers hate me for it. Mind that

1. You need to be careful to avoid "works on my machine" moments

2. You need to remember that you did it in case you need to undo it.

bat is certainly a game changer. I never printed things out to the terminal - always did a `less` or a `view` - before I installed bat.

One (very) minor issue I have with it is that when the file is very small - a couple words or lines at most - then the "decorations" it prints around the content get distracting and make the content slightly harder to read. Maybe I should just write a wrapper around it that does a `wc` first and decides whether to do a `bat` or a `cat`.

Every time I see these lists, I tell myself i'll start using these, but always forget.

I would love a meta tool that, every time I use one of the old tools, it automatically gives me a notice to use the new one instead, so I can learn. Then again I guess I could alias the old ones to point to the one one.

A new fave I recently discovered - render markdown in the terminal for easy reading (and proofing):

https://github.com/charmbracelet/glow

I recently found out about mdp too, a way to display markdown in the terminal as slides.

https://github.com/visit1985/mdp

> I recently found out about mdp too, a way to display markdown in the terminal as slides.

> https://github.com/visit1985/mdp

I use pandoc to convert markdown to powerpoint decks, it's a great workflow as you can preview and tweak the content and then apply the firm theme before the presentation.

Yeah, I just like the terminal aesthetic. And I've had a problem in the past with sales bros taking internal only presentations that aren't supposed to be consumed externally for a lot of reasons and showing them to customers. Markdown seems to be enough of a barrier to keep that from happening.
Do you mean actual PowerPoint or just creating a (presumably HTML based) presentation?
actual pptx file:

pandoc -f markdown input.md -o output.pptx

Glow is absolutely gorgeous! I wasn't aware of it before reading this article and I love it so much! I write most of my notes as Markdown files and Glow is the best tool to browse through them.
rdfind, it's excellent for finding duplicate files and deduplicating them.
No such list is complete without hexyl!

https://github.com/sharkdp/hexyl

"A command-line hex viewer" (for anyone else who wanted a one line description of what it is).
A replacement for xxd, which it seems like equally few people know about for some reason. Probably the reason it's forgotten about so often
One of his other tools, hyperfine, made the list. vivid is useful candy from him.
Nice tool - my muscle memory steers me toward bvi though.
I'm a big fan of jo[1] for making generating JSON from the shell not terrible.

[1] https://github.com/jpmens/jo

Very cool! jq is very powerful but can be clunky for simple operations, I love how simple this is
Glad to discover fd. I've always struggled with find syntax. It's easy enough, but always kind of fiddly IME.
I mostly use zsh's globbing for this these days; the syntax can be a bit intimidating at first, but it's not that hard once you get used to it, and it's very quick and easy to type.

Bash doesn't really have any of this, so if you're a bash user you're out of luck. Don't know about fish.

fd has been a life saver on windows dealing with tons of csv file lately.
yes! lots of new tools like FD are just easier to use on Windows than the GNU tools (My experience with a corporate laptop).
I create aliases/functions and maintain a cheatsheet for commands I don't use often (for ex: convert/ffmpeg/etc) .

    # fs 'foo' will find files/dirs with 'foo' anywhere in the name irrespective of case
    fs() { find -iname '*'"$1"'*' ; }
rclone is another useful cli tool I use frequently.
Mosh isn't a replacement for SSH, it uses it.

> The mosh client logs in to the server via SSH

This is a cool list overall though.

It only uses ssh for iniating the connection to leverage the authentication.
Semantics, semantics. If you mosh into a system, you wouldn't also ssh into it. In that sense, the use of mosh replaces the use of ssh and mosh would be used in similar scenarios.
The neat thing about mosh is that it doesn't rely on ssh. All you need is a way to launch a process on a remote machine and securely transmit a shared key back to the client. ssh happens to be a useful way to do this, but it's not required
Is mosh secure? Looks like it's been unmaintained for quite a few years.
I've been using it all day, every day for several years. It works quite well.
So does rsh. GP asked if it was secure, though.
Good for you! But the question was about it being secure, while answer is about something else.
We might be victims of our own success on some of this. We've never had a major security hole in Mosh (after ten years since 1.0). We're really proud of that! But that also means we've never needed to issue a security update, which some people use as a proxy for "are people looking for security holes in this project."

After a few years without an active maintainer, as of a few months ago we now have a group working slowly but actively towards a Mosh 1.4 release. I think the main benefit people are expecting will be support for 24bit color escape sequences, but I'm also hoping we can get some fuzz targets, etc.

Yes, because it’s underpinned by SSH it’s secure.

The authors consider it feature complete hence the lack of updates.

What? Outside of initial handshake, it doesn’t use ssh (which is kind of the point). It’s totally valid to ask about its security.
I'd like a command line tool that could transform `history` into a list of alternate tool recommendations. Bonus if it could also generate recommended aliases and functions according to your habits.
(comment deleted)
Ah, delta is missing! Right from the docs, it's "[a] syntax-highlighting pager for git, diff, and grep output".

[1] https://github.com/dandavison/delta

(edit: nevermind, somehow I missed it)

It's on the list, do a ripgrep for `a pager for git` ;)
Interestingly I was also about to post that autojump was missing, checked the comments, saw yours, and rechecked - sure enough, autojump is in there! So, your comment was useful after all.
Ah, htmlq [1] is a missing one that's not on the list!

Straight from the repo: "Like jq, but for HTML."

I find it useful for quickly hacking scripts together and exploring data. Very useful for the iterative process of finding good CSS selectors with the data that I can get without javascript running.

--- [1] https://github.com/mgdm/htmlq

I use pup for this. People who tried both, any difference?

https://github.com/EricChiang/pup

Not sure if pup supports this but something I do use fairly often (and copied into my own internal tooling) is the ability to filter out results as a flag in the CLI.

For example, something I usually do is:

  curl --include --location https://example.com | tee /tmp/example-com.html | htmlq --base https://example.com a --attribute href --remove-nodes 'a[href*="#"],a[href^="javascript"],a[href*="?"]'
This grabs the page, shunts a copy to /tmp for subsequent, iterative testing, then tries to grab all the links while filtering out any links that have a '#', '?', or start with the word 'javascript'. This is super helpful when I'm just exploring some HTML scrape and trying to build a graph of links without having to pop out a proper programming language just yet.
A-ha! I knew I had one more.

How many times have you wanted to dedup a (text) file, but definitely didn't have enough memory to perform the task? I found this one day when I had to dedup a set of .ndjson.gz files which totaled a cumulative 312 GBs. Utilizing the bloomfilter option, I was able to dedup the records without any large investment on my part.

Anyways, runiq[1], "[an] efficient way to filter duplicate lines from input, à la uniq".

It provides several ways to filter of which I almost always default to utilizing the bloomfilter implementation (`-f bloom`).

---

[1] https://github.com/whitfin/runiq

[2] https://whitfin.io/filtering-unique-logs-using-rust/

Has anyone made an installer/GNU type thing for the "common" ones like delta and rg? Could be a fun weekend project:

Select what tooling you want, it will be installed using your package manager

[ ] delta

[ ] bat

...

If you're on arch, most if not all these tools are in the official repos. Note that delta is named "git-delta".

  pacman -Syu git-delta bat ripgrep fd
Saved you a weekend ;)
(comment deleted)
Homebrew works great, even on linux. Every one of these nifty tools is available there.

asdf is another good option with most of them.

You can use Nix (https://nixos.org/nix) to install these tools on any Mac/Linux machine (nix profile install nixpkgs#{bat, delta}). Disclaimer: I packaged some of these tools for Nix :)
(comment deleted)
I could really use a better workflow to refine grep matches. Has anyone made a tool that combines grep (regex search) with fzf (multiple positive/negative patterns)? What I really want is something like:

  grep pattern1 **/* | grep pattern2 | grep -v exclude_these | grep -v also_exclude
The problem is this loses filenames and context lines in the output. I want to apply several positive and negative regexes, and only at the very end annotate with filenames and context. Anyone have a good workflow for this?
Lnav with filters? or can you stack -e expression arguments onto one grep command?
Are you ok with the initial list existing in memory?

Then I highly recommend: emacs / vim buffers

Just posting this without trying it out...grep -nH gives you line numbers and full filepath context, and as another commenter said, -ve allows you to string multiple excludes, so grep -inH <search> -ve not_this -ve nor_this -ve nor_that.
You don’t have to stack -v like that: -v inverts all the -e expressions, so this should be equivalent:

    grep -inHv -e foo -e bar -e baz
So, awk sort of works as a fancy grep:

    ps axjw | awk '(/zsh/ || /login/) && !(/awk/ || /direnv/)'
And you can easily add features like "print the first line unconditionally:

    ps axjw | awk 'NR == 1 {print} (/zsh/ || /login/) && !(/awk/ || /direnv/)'
IMO, awk is in a pretty uniquely sweet spot between grep and perl/ruby/python.
Thanks for the grep tip!

Unfortunately I've not put in the effort to learn awk past printing the n-th column of ls (my typical use) - the extra syntax required to properly 'quote' and {} things puts me off.

I glue together ripgrep with fzf and bat like this:

    rg --line-number --no-heading --color=always --smart-case "$@" | fzf -d ':' -n 2.. --ansi --no-sort --preview-window 'down:20%:+{2}' --preview 'bat --style=numbers --color=always --highlight-line {2} {1}'
I get a small preview of the file in the bottom 20% of my terminal, and I can use fzf's matching to further filter, or to exclude things

I capture the output and then `cut` it up to get filename and line number, which then get used to open the file/line in vim

If your grep has -P, then you could do all in one go with lookahead assertions...

    grep -P '(?=.*pattern1)(?=.*pattern2)(?!.*exclude_these)' **/* 
Maybe not the most beautiful or easy to have at the fingertips, but could be worse.
Not exactly what you’re asking for but similar: I wrote a script called aag, based on ag, that lets you find files that contain multiple matches anywhere in the file. It’s a per-file logical AND of multiple ag searches.

https://gist.github.com/b0o/f0759c84af6ef773a37a499fdb1c05af

Example: you’re trying to find a file that contains the strings “MIT License” (case insensitive), “npm install”, and a match for “react-.*” somewhere in your home directory:

    aag ~ ---- -i "mit license" --- "npm install" --- "react-.*"
The excessive dashes are necessary so that it’s possible to pass different options to each separate invocation of ag.

In case it’s not clear why this is useful, normally ag (or grep) searches are linewise. It’s not so easy if you are looking for things that occur on different lines, and possibly in different orders.

Perl would be one option:

  perl -ne '( /foo/ and /bar/ and !/baz/ and !/splat/ ) and print "$ARGV: $_"' *
I didn't include the context part, since that would be more than a one-liner, but it's not hard to do in a short script.
I do things like that inside Emacs with the consult-grep command from the Consult package, combined with the Orderless matching style, Embark to collect the results in a buffer. This has several advantages over the command line:

- Interactivity: the results are updated live as you type, so you catch typos sooner and can tweak the search terms as you go.

- The buffer of search results you collect with Embark is not dead text like it would be in the terminal, instead, each line is a link to the corresponding file taking you to the line that matched.

- Wgrep lets you edit all the matching lines in place!

Packages referenced:

1. Consult: https://github.com/minad/consult/

2. Orderless: https://github.com/oantolin/orderless

3. Embark: https://github.com/oantolin/embark

4. Wgrep: http://github.com/mhayashi1120/Emacs-wgrep/raw/master/wgrep....

I use skim / `sk` for this kind of task: https://github.com/lotabout/skim . For example, for iterating on jq incantations, I have in my shell rc file:

  function jqsk {
    sk --tac --ansi --regex  --query . --multi --interactive --cmd '{}' \
       --bind 'enter:select-all+accept,ctrl-y:select-all+execute-silent(for line in {+}; do echo $line; done | pbcopy)+deselect-all' \
       --cmd-history=${HOME}/.sk_history --cmd-history-size=100000 \
       --no-clear-if-empty \
       --cmd-query "cat $1 | jq --raw-output --color-output --exit-status '.'"
  }
I should look into whether fzf or any of the other tools in this thread can be coerced into doing the same thing, the above is pretty verbose and arcane, and it doesn't always behave the way I expect.
If the first grep has "-HRn" flags you then pass the file and line number information down the pipeline.

  -H File name
  -R Recursive (directories)
  -n Line number
you probably want awk or perl.

    awk '/pattern1/ && /pattern2/ && !/exclude1|exclude2/ {print FILENAME, $0}' */*
I peripatetically dive into "strace" for one-off debugging - is there something more modern I should be doing?
Perf. Extremely powerful. Mostly for profiling and also some scenarios of debugging. Takes a fair bit of getting used to and each debugging session need more setup, compared to just a quick strace. When working with containers it’s even more complicated to setup unfortunately.
broot completely changed the way I navigate directories on the CLI over the past year.

I was an 'ls' purist before, I've tried various CLI file managers in the past and they all felt like they added too much friction, with the one exception of nnn which I briefly used before finding broot, which just feels really fluid and natural.

Broot has many features that feel natural... when you know they exist (for example, try looking for what's taking space with `br -w` then stage the files and remove them at the end).

I suggest everyone to have at least a short glance at the introduction at https://dystroy.org/broot/

broot can't run commands on, let alone select, multiple files. A real shame.
I use spruce for many thing but it's ability to merge y'all files smartly is very useful. Think global yaml merged with one of [prod, staging, dev].yaml, merged with override.yaml creating a deployment yaml. https://github.com/geofffranks/spruce
A simple trick I only figured recently is following logs with fuzzy search:

  tail -f /var/log/foo.log | fzf +s
Or something similar for output from a dev server:

  make serve | fzf --ansi +s
I've been using tmux for finding, but I think this might be brilliant and stupid simple. Thank you for this! Never thought of piping "live" output or streaming to fzf!!
Could you (or anyone who understands) explain what these do?
It just takes the last ten lines of a log file, then passes that input to a program that basically lets you search each line. I don't really see the usefulness.

Edit: Ah, I see. According to another comment you see the output of the file as it changes.

`tail -f` follows the logfile, so the command allows you to search over the logfile as logs are being added to it
tail -f will hang around and output new lines that appear in the file.

fzf will receive that input and in this case accumulate the new lines that have come in from tail -f. It will then stay around, present an interactive full screen text ui, and let you interactively filter the set of received lines based on substrings you enter at the fzf prompt. This while continuously incorporating new log lines coming from the pipe, from tail -f. The +s just says not to sort the lines, keeping the matches in the same order they appeared in the logs.

Speaking of logs, angle-grinder is amazing: https://github.com/rcoh/angle-grinder
That looks awesome. Something I'd love help with, I use pdsh to tail logs from multiple servers at once, but the ways I can manipulate the logs feel really limited because of how pdsh works. Does anyone know of a better solution for that? Like, from a head node, aggregate/tail the contents of the same log file on multiple servers. Bonus points if it uses 'genders' too to get the list of servers.
The Logfile Navigator (https://lnav.org), a TUI for viewing log files, has support for opening logs on remote hosts via SSH in its latest version. See the following post for more information: https://lnav.org/2021/05/03/tailing-remote-files.html

As for integrating with a “genders” host DB, there’s no direct support for it. But, lnav is scriptable, so I’m pretty sure it’s possible to write a script that does what you want. I can help with that if post in the github discussion: https://github.com/tstack/lnav/discussions

Alternatively, you can use less(1) in tail mode to search growing logs.

  less +F -p pattern /path/to/log
(Ctrl-C to break out of tail mode. /pattern to interactively set search pattern.)
Also while inside less: & shows you only lines which match a pattern. You can hit & multiple times and less will show you only those lines which match every input pattern. A ^N right after & negates the pattern. & respects the -I switch (case insensitive pattern matching).

I use this all the time, especially when I'm on a machine that I don't want to bother installing something like fzf on.

Good tips. Small correction: `&` only filters by the most recent pattern.
Seems to depend on your particular less, see the last sentence of this paragraph from `man less` on my machine:

       &pattern
              Display only lines which match the pattern; lines which do not
              match the pattern are not displayed.  If pattern is empty (if
              you type & immediately followed by ENTER), any filtering is
              turned off, and all lines are displayed.  While filtering is in
              effect, an ampersand is displayed at the beginning of the
              prompt, as a reminder that some lines in the file may be
              hidden.  Multiple & commands may be entered, in which case only
              lines which match all of the patterns will be displayed.
Indeed, I thought it would behave like you describe.. when I was refreshing my memory of how the negative pattern filtering worked, I first did &/pattern and then &/^Npattern, and was surprised to see that it displayed zero matching lines.

this is my version of less:

  % less --version
  less 581.2 (POSIX regular expressions)
  Copyright (C) 1984-2021  Mark Nudelman
This is amazing! Is it possible to do the following somehow?

- automatically have this for any command that outputs more than 10 lines?

- automatically exit when the main command (for example a dev server) exits?

- print the output of the main command to stdout after this is done?

Maybe with some clever use of zsh hooks? Here's a gist for zbell; it uses `preexec` and `precmd` to run something right before a command is executed (`preexec`) and right before the prompt is shown again (`precmd`)

https://gist.github.com/jpouellet/5278239

Mine blinks a little light if a command finishes after 30 seconds, and sends me an email if something takes over a minute.

> automatically have this for any command that outputs more than 10 lines?

Probably not. The output of a command typically goes directly to the terminal and does not pass through the shell, so the shell has no idea how many lines there are.

You could write a shell where that's not the case, but that would have issues with interactive things - what happens if you run e.g. vim or htop in that context?

You can pipe to `less -F` (`--quit-if-one-screen`), but note that the version of `less` shipped with macOS has a bug and might just swallow the output instead.

More likely is a feature to skip processing on short outputs, like `less -F`

``` -F ........ --quit-if-one-screen Quit if entire file fits on first screen. ```

That's a pretty neat trick. I was using `watch -n1` with grep for this occasionally but this is so much better!
fzf is a wonderful little tool. I use this script so much:

git branch | fzf | xargs git checkout

(comment deleted)
Excuse my ignorance, but what does this command do?
It pipes a list of available git branches into fzf, which lets you filter them by fuzzy string match. When you hit enter, it will take the best matching one and switch to that branch

            _ ._  _ , _ ._
          (_ ' ( `  )_  .__)
        ( (  (    )   `)  ) _)
       (__ (_   (_ . _) _) ,__)
           `~~`\ ' . /`~~`
                ;   ;
                /   \
  _____________/_ __ \_____________
Related git+fzf:

    [alias]
      fza = "!git ls-files -m -o --exclude-standard | fzf -m --print0 | xargs -0 git add"
Then if you run "git fza" you'll get a list of changed files in your repo, which you can use TAB to select/deselect. Hit enter and the selected files will be staged, ready for a commit. Extra cool is that it works from any subdirectory of your repo because it always lists files from the root of the repository. It's really useful for selectively adding lots of files from the command line.

I then alias "ga" to "git fza" for even less typing :)

I’m a fan of nnn for a terminal file manager, so I’m keen to try out broot. Does anyone have other recommendations I should try?

https://github.com/jarun/nnn

How does nnn compare to ranger https://github.com/ranger/ranger ?
ranger is fancier (both visually and in terms of configurability), but nnn is significantly faster in my experience. I kept putting off looking into ranger's rifle capabilities and Python scripting, but after having it crash on me a couple times - in a directory with many hundreds of files, to be fair - I tried nnn. The speed and simplicity made me switch over entirely, because it has just the right amount of features that I wanted from ranger. (Well, the one thing I kinda miss is the inline Markdown preview in ranger - shortcut `i` - but it's a minor convenience at best.)
Midnight commander
MC only here too. On Amiga Directory Opus (DOpus) was amazing. Their windows port came late and isn't so essential, though I can't imagine how people have the patience to do any file management with awful normal explorer. Luckily not a worry of mine, I live in the nix/nux terminals.
pwru (https://github.com/cilium/pwru) is a fun new tool from the Cilium folks for tracing network packets in the kernel. Like tcpdump but you can trace the full path of the packet including kernel syscalls. Lets you debug much deeper than "when the packet gets to this port it gets dropped".