# Fish shell

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

Not the aquatic creatures, 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 design opinions, at least you might appreciate it has a healthy degree of sarcasm in said opinions, which sarcasm is sorely absent from the drearily earnest nerdview of your typical gnu.org project. You might also hold that having any kind of principled opinion is better than the design-by-accumulation-of-tradition-cruft which structures command-line shells.

## Configuration

### Modifying the PATH

This is the most confusing thing in fish for me. It is worth reading tutorials, e.g.

tldr:

fish_add_path /usr/local/bin

To remove a path

set PATH (string match -v /usr/local/bin $PATH) Adding a path? Say it’s /usr/local/bin. Put set -gx PATH /usr/local/bin$PATH

in ~/.config/fish/config.fish, OR

set -U fish_user_paths /usr/local/bin $fish_user_paths Removing a path? set -gx PATH (string match -v /usr/local/bin$PATH)

🏗 explain the difference between $PATH and $fish_user_path which will depend upon me understanding how the content of $PATH magically replenishes itself and the difference between “universal” and ”global” variables. ### Modifying any settings with GUI fish_config ### Traditional config Put commands in ~/.config/fish/config.fish. ## Plugins You can hack fish. Popular plugin management systems exist also. AFAICT a passable default is oh my fish curl -L https://get.oh-my.fish | fish fisher seems to be around too? curl -sL https://git.io/fisher | source && fisher install jorgebucaran/fisher It also handles omf plugins, apparently. The omf manual is brusque. See a helpful blogpost. I am currently running omf, but since it intrusively changed my prompt I am grumpy at it. However, I got a better prompt, spacefish. omf install spacefish It does need the wacky powerline fonts. sudo apt-get install fonts-powerline There are various useful plugins that are not purely cosmetic; For example fzf adds fuzzy history search. z does recency/frequency-based directory navigation. ## homebrew compatibility on ubuntu Since I use fish shell as my default but ubuntu automatically execute s the bash startup script .profile on login I ran into the following errors on login, when it tried to run the fish init in a bash process: bash: set: -g: invalid option set: usage: set [-abefhkmnptuvxBCHP] [-o option-name] [--] [arg ...] bash: set: -g: invalid option ... This is maybe related to an intermittently reported bug in homebrew. The fix that worked for me was to change the automatically-added line in .profile to be eval$(SHELL=bash /bin/brew shellenv)

eval (env SHELL=fish /bin/brew shellenv)

to ~/.config/fish/config.fish.

## Python environments

### virtualenv

if you are still using virtualenv on python you will need virtualfish to replace python’s virtualenvwrapper.sh. 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? Either that or you are barred from using fish by policy and this is not a problem.

### Using anaconda python

You need to do some extra setup to use conda with fish.

~/miniconda3/bin/conda init fish

Or, for older versions,

source ~/miniconda3/etc/fish/conf.d/conda.fish

into ~/.config/fish/config.fish.

(Replace ~/miniconda3/ with the output of conda info --root if you used a non-standard install location)

## Vars, expansions, extensions, suffixes

Wildcards are minimal, just *, **, and brace expansion, mv a.{txt,html.

For more sophisticated string processing, one defines custom functions (which I never actually do) or use classic subcommands which I do all the time.

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

or expansion via string, which is harder to

for file in (ls *.html)
mv $file (string replace -r "\.html\$" .txt $file) end ## For loops while true echo "Loop forever" end ## Test exit status if test$status -eq 0
echo yeah
end

To simply execute the second command if the first succeeded the command you want is and, which is hard to google for:

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

## Temporary variable setting uses env

env FOO=BAR baz.sh

## Aliases, custom commands

• Command allows overwriting a command.
• Alias makes an alias, but is lacking autocomplete.
• Abbr makes a sort of alias that will expand out and support autocomplete.

## Misc

### No comments yet. Why not leave one?

GitHub-flavored Markdown & a sane subset of HTML is supported.