Handy Shell Tools

During the „corona lockdown“ I happened to join much more screen sharing sessions than usually. That’s when I saw a bunch of interesting things happen on one of my hackerspace collegues‘ screen, the other day. When I asked him what kind of shell tools he was using, we started discussing the tools we use often or like very much. So I thought I should share some of those with you :)

bat

bat is meant to be a cat substitute, but to me it feels more like a kind of less alternative. You can clone it from GitHub https://github.com/sharkdp/bat
And here’s the manpage.

It’s clever enough to know if it’s output is piped to another program or file. So that when you do a bat file1.txt | less you don’t see the line numbers or the color sequences. It’s a pretty big binary (4,3M) so after all it can’t really mess with cat (which is actually just 43k big), I think.

Permissions Size User Date Modified Name
.rwxr-xr-x  4,3M root  7 Mai 23:08  /usr/bin/bat
.rwxr-xr-x   43k root 10 Mär 22:22  /bin/cat*

But anyway, I set up an alias in my bash_aliases to try using it as a eye candy version of less :)

$ cat .bash_aliases | rg bat
alias less='bat'
$ type less
less ist ein Alias von `bat'.

And I’m happy so far.
This is what it looks like (it automatically recognizes the programming language for syntax-highlighting \o/):

exa

exa tries to be a modern version of ls. It’s code can be cloned from GitHub https://github.com/ogham/exa
I like it’s neat colored output. That’s why I aliased it instead of alias ll="ls -alh" I am using alias ll="exa -alh"now and I like it so far :)
But it’s just like bat and catexa is much bigger (1,4M) than ls (141K):

Permissions Size User Date Modified Name
.rwxr-xr-x  1,4M root  7 Mai 23:00  /usr/bin/exa
.rwxr-xr-x  141k root 10 Mär 22:22  /bin/ls

It’s command line options or arguments are pretty similar to those of ls.
exa -alhF looks like this:

I really like colorful outputs :)
Here’s the manpage.

rg ripgrep

rg or ripgrep is a tool like grep but it’s newer and faster. It says it’s specialiced to codesearch. I’m just trying it out and combined with tools like fzf I really start to like it. You can read about all the details on Github. There is a neat comparsion of how commands to solve a certain problem look like with different tools like ag, rg or grep. The authors themselves put a list of reasons together why you should use rg instead of grep: https://github.com/BurntSushi/ripgrep#why-should-i-use-ripgrep
https://github.com/BurntSushi/ripgrep/blob/master/FAQ.md#posix4ever

fzf

fzf really blew my mind :) It’s so unbelieavable handy that I don’t know where to start. You can check out it’s code on Github. In general it’s like a fuzzy search or how they call it a general purpose command-line finder. But you can use it with vim or emacs or really a lot of other programms. Like rg or you can use it to show commandline completions if you are using bash-completions or something similar or even if not. You can confiure the hell out of it. I guess there’s nothing that you can’t configure :D
I really like the preview function.

Preview
       --preview=COMMAND
              Execute  the  given command for the current line and display the result on the preview window. {} in the command is the placeholder that is replaced to the
              single-quoted string of the current line. To transform the replacement string, specify field index expressions between the braces (See FIELD INDEX  EXPRES‐
              SION for the details).

              e.g.
                   fzf --preview='head -$LINES {}'
                   ls -l | fzf --preview="echo user={3} when={-4..-2}; cat {-1}" --header-lines=1

              fzf exports $FZF_PREVIEW_LINES and $FZF_PREVIEW_COLUMNS so that they represent the exact size of the preview window. (It also overrides $LINES and $COLUMNS
              with the same values but they can be reset by the default shell, so prefer to refer to the ones with FZF_PREVIEW_ prefix.)

              A placeholder expression starting with + flag will be replaced to the space-separated list of the selected lines (or the current line if no  selection  was
              made) individually quoted.

              e.g.
                   fzf --multi --preview='head -10 {+}'
                   git log --oneline | fzf --multi --preview 'git show {+1}'

              When using a field index expression, leading and trailing whitespace is stripped from the replacement string. To preserve the whitespace, use the s flag.

              Also, {q} is replaced to the current query string, and {n} is replaced to zero-based ordinal index of the line. Use {+n} if you want all index numbers when
              multiple lines are selected.

              A placeholder expression with f flag is replaced to the path of a temporary file that holds the evaluated list. This is  useful  when  you  multi-select  a
              large number of items and the length of the evaluated string may exceed ARG_MAX.

              e.g.
                   # Press CTRL-A to select 100K items and see the sum of all the numbers.
                   # This won't work properly without 'f' flag due to ARG_MAX limit.
                   seq 100000 | fzf --multi --bind ctrl-a:select-all \
                                    --preview "awk '{sum+=} END {print sum}' {+f}"

              Note that you can escape a placeholder pattern by prepending a backslash.

              Preview window will be updated even when there is no match for the current query if any of the placeholder expressions evaluates to a non-empty string.

       --preview-window=[POSITION][:SIZE[%]][:noborder][:wrap][:hidden]
              Determines  the layout of the preview window. If the argument contains :hidden, the preview window will be hidden by default until toggle-preview action is
              triggered. Long lines are truncated by default.  Line wrap can be enabled with :wrap flag.

              If size is given as 0, preview window will not be visible, but fzf will still execute the command in the background.

              POSITION: (default: right)
                  up
                  down
                  left
                  right

              e.g.
                   fzf --preview="head {}" --preview-window=up:30%
                   fzf --preview="file {}" --preview-window=down:1

You can read the whole manpage here.
And there are lots of examples here.. Try it out and see for yourself. But be warned: once you start to live with fzf, you can’t live without it again :D

ip

By the way: did you know that ip has a color option, now? If you use it like this ip -c a instead of just ip a it looks like this:

auf dem Bild sieht man den Output von ip -c a.

Which, I think, is very nice <3
The manpage says this about the -c option:

-c[color][={always|auto|never}
              Configure color output. If parameter is omitted or always, color output is enabled regardless of stdout state. If parameter is auto, stdout is checked to
              be a terminal before enabling color output. If parameter is never, color output is disabled. If specified multiple times, the last one takes precedence.
              This flag is ignored if -json is also given.

              Used color palette can be influenced by COLORFGBG environment variable (see ENVIRONMENT).

So much for now… I hope you found one or two handy programms in this article. Have fun!