The Living Thing / Notebooks :

Fish shell

A command line shell that does not think that the problem is you

Not the aquatic creature, but rather the command-line doohickey, which is not as shit as the other ones. I’m gradually transitioning to fish, after accidentally losing a lot of precious data due to a quirk in bash syntax. Long boring story. It’s time for new, exciting, different stupid errors.

fish has a strong fanbase and an opinionated design. If you dislike those opinions, at least you might appreciate it has a healthy degree of sarcasm in its opinions, which sarcasm is sorely absent from the drearily earnest nerdview of your typical project. You might also hold that having some kind of opinion is better than the design-by-accumulation-of-cruft which structures traditional command-line shells.

Pro tips

modifying the search PATH

Adding a path? Say it’s /usr/local/bin. Put

set -gx PATH /usr/local/bin $PATH

in ~/.config/fish/

Removing a path?

set -gx PATH (string match -v /usr/local/bin $PATH)


set -U fish_user_paths /usr/local/bin $fish_user_paths

TODO: explain the difference between $PATH and $fish_user_path which will depend upon me working out how the content of $PATH magically replenishes itself.

Python environments


if you are still using virtualenv on python you will need virtualfish to replace python’s Or switch to native python3 venv, which is more or less the same thing but works better and doesn’t support python 2. But if you need to support python 2 at this stage it’s because you are in some weird enterprise environment with horrid legacy software, so hopefully you can farm this problem out to the tech support team?

Using anaconda python

You need to do some extra setup to use conda with fish. Specifically, add the line

source ~/anaconda3/etc/fish/conf.d/

into ~/.config/fish/

(Replace ~/anaconda3/ with the output of conda info --root if you used a nonstandard install location)

Now you can activate an anaconda environment, e.g. the default base environment:

conda activate base

Modifying any settings with GUI


Vars, expansions, extensions, suffixes

Use classic subcommands.

for file in (ls *.html)
    mv $file (basename $file .html).txt

or string expansion

for file in (ls *.html)
    mv $file (string replace -r "\.html\$" .txt $file)

For loops


while true
    echo "Loop forever"

test exit status

Similar to bash, but not identical.

if test $status -eq 0
    echo yeah

Temporary variable setting uses env


Execute the second command if the first succeeded

The commmand you want is and, which is hard to google for

../bin/ foo; and cp foo ~/Dropbox/

aliases, custom commands

command, alias, or abbr?