A friendlier command line environment
I spend a lot of time making the command line as useful to me as possible. This means seeking out a lot of tools, tips and tricks and putting them to the test. I've found a lot of tools that replace a standard unix tool by being faster, friendlier, easier, or saner-by-default. Other tools fill a new role in my cli toolkit and often become indispensable.
A better shell - fish
fish is the friendly interactive shell.
It's a replacement for bash, both as an interactive cli, and as a scripting language.
Pros
- Documentation and a tutorial
-
As you type any command, fish autosuggests you matching commands from your history, and pressing <right> selects it. This leaves you free to edit the selected command if it isn't exactly what you need.
-
fish provides as you type syntax highlighting of your command line. This makes it clear if a command exists, if a path is valid, and if there are unmatched quotes and parentheses, all without pressing enter.
-
fish comes with tab completions for many common commands, and tool authors can create their own completion definitions. Completions are simple enough to create that you can create them for your own scripts, and for tools that don't provide them.
-
In bash and other shells you can shoot yourself in the foot by not quoting your variables exactly right. In fish you shouldn't have to worry about quoting your non-list variable substitutions.
-
fish syntax is a lot cleaner, because it gets rid of a lot of older cruft kept for backwards compatability.
-
fish has lists unlike
sh
, and its lists are much nicer to use thanbash
lists. fish lists are one-indexed.Fish lists have:
-
Negative indexes
set arr 1 2 3 4 echo $arr[-2]
> 3
-
Enough slices
set arr 1 2 3 4 echo $arr[2..3] echo $arr[-1..1]
> 2 3 > 4 3 2 1
-
Smart expansion
set arr 1 2 3 4 count $arr count "$arr"
> 4 > 1
-
Cartesian products
set numbers 1 2 set letters a b echo $numbers$letters
> 1a 2a 1b 2b
-
Negative indexes
-
fish will auto-load functions defined in individual files under
~/.config/fish/functions/
, no$PATH
munging necessary. Useful for things more complex than an abbreviation, but less than a full script.
Cons
-
fish is not a POSIX compatible shell. Many tools that assume your shell is
will break (e.g. tramp in emacs, brew), and you'll sometimes have to do a bit of
translation of commands you find online. In cases where tools assume your shell in
order to set environment variables, you can typically use
bass
as a compatibility layer.
keyboard shortcuts
fish has quite a few handy command line keyboard shortcuts
-
alt-v
edit current command in your$EDITOR
. On quit it returns to fish with the edits in place. Useful for long command lines, or edits that are better suited for real editor. alt-h
bring up man page for current command if it existsalt-p
appends| less
to the command so it is pagedalt-l
lists current directory, or the directory path the cursor is over- And more
abbr over alias
alias
is the standard, convenient and easy to use solution to the problem of
having to type long command names and options for things you do all the time,
but it isn't as good as it could be.
One problem I have with alias is it's easy to forget what lies behind the
easy to type facade. This leads to a couple different problems.
When using alias I would sometimes run into the problem of asking a coworker
"xyz command isn't behaving like xyz does for you, why is that?" and it turns
out one of us had aliased xyz
to xyz --some-flag
and forgotten about it.
If you needing to run a slightly different version of your alias, you
have to spend time looking up what the real command is. For example, if xyz
is aliased to xyz -abc --long-flag
, and I realize in this case I actually
want to run xyz -ab --long-flag
. With alias I have to look up what command
xyz
actually is, and then get it into my command line to make the minor edit.
This is where abbr comes in. It's a fish builtin meant to replace alias. abbr works similarly to alias, except when you type in the abbreviation, it expands the abbreviation to the full text in the command line, allowing you to always see exactly what you're about to run, and to make any edits necessary with minimal effort. This makes it harder to forget what is actually being run, and allows you to adjust the command for your current situation before running it.
CLI Tools
grep - ripgrep
Replace grep
with the faster and easier to use alternative rg
.
File name search - fd
Replace find
with the much, much easier to use fd
Directory listing - exa
exa
has nicer coloring than ls
, good help and some nice options.
You should definitely abbreviate it to ls
though :|.
JSON parsing and manipulation - jq
jq
is the best way I have found to filter, query, and manipulate json.
Archive extraction - e
Automatically extracts archives based on some simple rules. Forget even further how to use tar
.
Pipe statistics and monitoring - pv
pv
gives stats on data passing through a shell pipeline.
Document conversion - pandoc
Convert between a large number of document formats.
Process visibility and analysis - htop
htop
is a far superior version of top
. It has colors, and a much better interface.
File viewing - bat
Replace cat
and less
with one tool. It has syntax highlighting,
line numbers, separates the printed files, all while paginating. If it detects it's not
outputting to a TTY, it behaves like normal cat
.
Hex dump - hx
A nice colorful hexdump utility.
Python REPL - ipython
A better python repl.
Count lines of code - tokei
Replaces cloc
to count LOC. It's fast!
Terminal splitting and sessions - tmux
Keep long lived shell sessions and multiplex terminals within one window.
CSV tooling - xsv
Munge CSVs, quickly and easily.
A sillier base64 - base100
Encode data as emoji. Similar to base64, but worsebetter.