
An Illustrated Guide to Useful Command Line Tools - signa11
https://www.wezm.net/technical/2019/10/useful-command-line-tools/
======
aquova
I quite like this list, there are a number of utilities here that I already
use on a daily basis. There are also a few utilities that I like that weren't
on this list, or some alternatives to what was shown. Some off the top of my
head:

\- nnn[0] (C) - A terminal file manager, similar to ranger. It allows you to
navigate directories, manipulate files, analyze disk usage, and fuzzy open
files.

\- ncdu[1] (C) - ncurses disk analyzer. Similar to du -sh, but allows for
directory navigation as well.

\- z.lua[2] (Lua) - It's an alternative to the z utility mentioned in the
article. I haven't done the benchmarks, but they claim to be faster than z.
I'm mostly just including it because it's what I use.

[0] [https://github.com/jarun/nnn](https://github.com/jarun/nnn) [1]
[https://dev.yorhel.nl/ncdu](https://dev.yorhel.nl/ncdu) [2]
[https://github.com/skywind3000/z.lua](https://github.com/skywind3000/z.lua)

~~~
rovr138
And regarding ncdu, there are static binaries for Linux. Just put them in a
folder and use them.

~~~
wodny
Nice. I've missed the static binaries on the homepage and should have tried
static compilation myself. Now my little python2 and find-based scripts
exporting ncdu-compatible outputs[1] on systems without ncdu seem a bit
redundant. On the other hand, there are some examples of filtering the output
with jq.

[1]: [https://github.com/wodny/ncdu-export](https://github.com/wodny/ncdu-
export)

------
atonalfreerider
An observation: I have always taken the meaning of the word "illustrated" to
specifically refer to non-lexical graphics. Searching the dictionary
definition of the word, I find a looser definition that applies to "examples"
intended to aid an explanation.

This is a similar cognitive dissonance to when I first learned that "Visual
Basic" and "Visual Studio" meant that the syntax of the displayed code was
highlighted, not graphically represented in a non-lexical way.

~~~
Sharlin
I’ve always assumed that the ”Visual” in VB and others refers to the WYSIWYG
drag’n’drop interface for creating GUIs.

~~~
dickeytk
Same here—though for the same reason I always thought "VSCode" was a strange
name since it doesn't have any of those interfaces.

------
dblotsky
I’m gonna sound like an old person here. As much as these tools are gorgeous
and ergonomic, remember that the others are standard, which means they’re
available (almost) everywhere.

Still though, these alternatives seem great for productivity locally, even if
they’re not usable in a script.

~~~
dickeytk
I’ve actually found myself using these to get me much more proficient in the
Shell overall. fd in particular is so much easier to use I find myself doing
things like:

    
    
      fd .log$ -x mv {} {.}.bak
    
      (Rename *.log to *.bak)
    

Can I do that with xargs, awk, and find? Yes, but every time I have to look up
the man page to at least one of them and it’s enough friction that I might
just open it in finder if it’s a handful of files.

Having some of these utilities around is a crutch that let me leverage the
entire ecosystem much more when I don’t have it. And when I do log into a
shared enviroment and don’t have my crutch, then it’s easy to fill in the
missing puzzle piece because it’s one part that’s missing and I’ve got the
rest of the environment down.

Of course if all you do is shared environments I wouldn’t suggest these, but I
would encourage people to use these to get more familiar with the CLI
ecosystem.

~~~
rhizome
bash/zsh: for f in *.log; do mv "$f" "${f/%log/bak}"; done

a bit more generic, `for` loops and parameter expansion are good to know for
proficiency, and also I dislike typing curly braces.

~~~
mtzet
This doesn't move files in subdirectories? Or am I missing something?

~~~
pfortuny
You are right, it does not. But the find command is not too complicated, or
different from the one above.

~~~
dickeytk
find has awful ergonomics that are completely unlike any other common unix
tool. I can never remember the syntax, how the flags work, or what order
things need to be in.

Let's use an example I just dug up of using find:

To list and remove all regular files named core starting in the directory
/prog that are larger than 500KB, enter:

    
    
      find /prog -type f -size +1000 -print -name core -exec rm {} \;
    

OK first, how in the hell is 1000 == 500kb? Is that a bug in my example[0]?
What does `-print` do exactly? And that backslash at the end? I have no clue
what that signifies. I'm never going to remember this madness. I'd probably
have resorted to writing a bash script in a file by now. But with fd it
becomes manageable and memorable for future tasks:

To list and remove all regular files named core starting in the directory
/prog that are larger than 500KB, enter:

    
    
      fd --type=file --size=+500k ^core$ ./prog -x rm {}
    

Now that's something that makes immediate sense even if you've never touched
the tool before. Not to mention, it doesn't end up in my .git and other
ignored directories.

[0] [https://kb.iu.edu/d/admm](https://kb.iu.edu/d/admm)

~~~
jodrellblank
Your fd command:

Why type=file and a size? What else has size in 500k range on a filesystem,
except files?

=+500 isn’t how math works, that’s implying it could be -500 or using equals
for an inequality because the commonly used greater than symbol is off limits,
it’s a learned bodge.

500kwhats? Bits? Bytes? Base2? Base10? Can I put a suffix on, is it kB and kb
case sensitive?

Why is your filename on the left of the folder you want to look in? That’s so
backwards to the left to right order /folder/files are normally written.

Why do you have some arguments with double dash, some with single dash, some
with no arg name at all, what’s the pattern for any of that?

What’s -x and why is it short for a word beginning with E?

Why is the find command executing anything at all?

It’s no more immediately sensible than find, it’s inconsistent scribble and
workarounds you’ve learned instead of the same that you haven’t learned.

~~~
coldtea
> _Why type=file and a size? What else has size in 500k range on a filesystem,
> except files?_

Directories. They have a size depending on the metadata list of included files
they contain. And can retain their size even if their inner files are deleted
(until some cleanup style process is run).

> _It’s no more immediately sensible than find_

Oh yes, it is.

The same nitpicking for find would take 10 days, and wont be as contrived...

------
aquova
A number of the utilities mentioned here (bat, fd, hexyl) are made by the same
author, who makes a number of additional command line utilities in Rust.
They're all rather easy to use and aesthetically pleasing, I'm a fan of their
work: [https://github.com/sharkdp](https://github.com/sharkdp)

~~~
29athrowaway
This man is also creating awesome tools:
[https://github.com/BurntSushi](https://github.com/BurntSushi)

------
matthewaveryusa
I always find exotic command-line tools cool but they never stick because Im
constantly sshing/using/targeting a variety of systems I don't own that don't
have them readily istalled

~~~
k_sze
If you have access to the build tools, you can compile and install stuff in
your home directory.

A bit tedious, but you would still get to use your favourite tools.

~~~
dickeytk
Encryptable, portable home directories is one of the goals of systemd. I can’t
wait until one day when I just ssh in and it’s all there

------
floatboth
I would add

[https://github.com/drbig/snb](https://github.com/drbig/snb)

[https://github.com/dandavison/delta](https://github.com/dandavison/delta)

[https://github.com/MitMaro/git-interactive-rebase-
tool](https://github.com/MitMaro/git-interactive-rebase-tool)

------
leshow
As much as I do use a number of these tools, there's something to be said for
being able to use any box you ssh or log into that has the default tools
available on any *nix system. ls, cat, find, etc. I'm hypocritical a bit in
that I do use rg, and fd, but I just can't bring myself to deviate too far
from the 'default'.

~~~
dblotsky
I often use the term “standard” in place of “default” there.

------
enriquto
really bad name for "dot", it has always been the graphviz interface

~~~
jolmg
Indeed, and graphviz's dot is really useful, too. It makes it really easy to
make all sorts of graphs. For example, if I wanted to make a dependency graph
of all the packages I have installed in Archlinux, I can use it like this:

    
    
      pacman -Qq | xargs -r pacman -Qi | awk '
        BEGIN { print "digraph deps {" }
        /^Name/ { n = $3 }
        /^Depends On/ {
          for (i = 4; i <= NF; i++)
            print "  \"" n "\" -> \"" $i "\";"
        }
        END { print "}" }
      ' | dot -Tsvg > package-deps.svg

------
claudiawerner
The guide mentions a dotfile manager, but here's something I found[0] on HN a
while ago that's really cool: just make your home folder a git repository.

[0]
[https://news.ycombinator.com/item?id=11071754](https://news.ycombinator.com/item?id=11071754)

------
naikrovek
Amazing how many of those are written in Rust and Go.

~~~
degraafc
I don't think it says much about the tools themselves though, it just makes
sense when you look at the author's GitHub and see a bunch of Rust projects.

~~~
epage
I think there are a couple of relevant factors

\- Can be distributed as a single binary, not requiring an interpreter and
virtual environment. \- Being more fun to make a hobby tool in due to minimal
footguns compared to C/C++. \- Really good dependency management and build
tool making it easy to compose these CLIs out of powerful building blocks (at
east for Rust). For example, ripgrep is broken up into a lot of packages that
you can compose together to make your own custom tool.

------
wodenokoto
Can someone explain the misuse of cat, which bat solves?

~~~
eurg
Catting a file will your terminal make interpret escape codes in the file.

For instance:

    
    
        $ echo -e "\033]0;${USER} is an unfriendly person\007" > test-file.txt
    

Then, many days later:

    
    
        $ cat test-file.txt
    

will change your terminal title.

With less, you _can_ interpret escape codes, but usually you don't, and I
consider this the correct default.

~~~
enriquto
in your example it is not cat who "interprets" the escapes, but echo

~~~
eurg
Neither one interprets the sequence, but cat will print the file unfiltered to
stdout, and stdout is processed by your terminal, and then the terminal will
interpret it. less filters before printing to the terminal.

~~~
enriquto
I meant that "echo -e" transforms the four characters "\033" into a single
byte, for example. Thus, the sequence is "interpreted" by echo. Then, the cat
program just copies the bytes without looking at them. If you want "cat" to
escape these bytes so that they are not seen by the terminal you can use the
"-v" option.

~~~
kortilla
The sequence that translates to an escape code is interpreted by echo. The
escape code is passed unfiltered by cat for the terminal to interpret.

------
fnord77
No mention of things that have gained a lot of traction, like `ag` and `fzf`

ag: - silver searcher, fast parallelized recursive grep that can abide by
things like `.gitignore`

fzf: - fuzzy finder

powerline-shell - $PS1 on steroids

~~~
epage
It does mention rg which is in the same category as ag and, maybe this is my
own bias, seems to have more mindshare now.

~~~
ibly31
Agreed - I used to use Ag but switched to Ripgrep. Better in every single way,
in my opinion. It's obscenely fast and has good defaults

------
spoki0
What about yq, for parsing the increasing amount of yaml? Though there seems
to be multiple competing tools by the same name...

[https://github.com/mikefarah/yq](https://github.com/mikefarah/yq)

[https://github.com/kislyuk/yq](https://github.com/kislyuk/yq)

------
mxschumacher
in order to avoid having to unlearn commands like cat and ls, I use aliases to
invoke bat and exa.

Here's a screenshot of my fish config:
[https://twitter.com/mxschumacher/status/1168993005744918528](https://twitter.com/mxschumacher/status/1168993005744918528)

~~~
dickeytk
I would do

    
    
      alias ls "exa"
      alias ll "exa -ll"
    

That way you get the nice shorter output which comes in handy for piping ls
things like:

    
    
      ls -d | xargs ls
    

Lists the files in subdirectories.

~~~
mxschumacher
good idea - thank you!

------
sbr464
Nice post! Surprised to not see httpie mentioned.

------
tambourine_man
Lots of cool stuff in here. I’m going to have a long look at Restic and
Syncthing.

I’d like to know why Skim instead of FZF. They are pretty similar but I’ve
been using the latter for years and would like to know of any possible
advantages to it.

~~~
floatboth
There's _a lot_ of these pickers and they are indeed similar. I've been using
[https://github.com/jhawthorn/fzy](https://github.com/jhawthorn/fzy) since
it's not fullscreen and has a really good matching algorithm.

~~~
apjana
fzy is cool and probably underrated. It's the preferred fuzzy utility for file
manager nnn too.

------
the_greyd
My code editor does a fair job of finding things for me, I know I won't use
ripgrep/fzf that often :shrug: On the other hand I would recommend fish shell
(replacement for bash) with z plugin and http (replacement for curl).

------
mahesh_rm
An alternative to z, which I find a little bit "smarter" is autojump.

------
madengr
What’s the terminal prompt shown the graphics?

