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 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 opinion is better than the
design-by-accumulation-of-cruft which structures traditional command-line
shells.
Installing
- Ubuntu users can get an updated fish PPA.
- or, macOS/Linux: install using Linuxbrew.
Plugins
Plugins are managed via oh my fish
curl -L https://get.oh-my.fish | fish
or by fisher.
curl https://git.io/fisher --create-dirs -sLo ~/.config/fish/functions/fisher.fish
The omf
manual is surly. 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 one, 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.
Configuration
Modifying the search 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
.
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)
and to add
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?
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
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