9 fishy Tips

Posted by Uwe Schaefer on Mon, Jan 1, 2018
In: Ops Linux
Tags: shell bash fish

TL;DR; take me to the Tips already

What & Why

Fish is an awesome shell, and for me a natural bash replacement. The website sums it all up:

Why fish?

fish is a fully-equipped command line shell (like bash or zsh) that is smart and user-friendly. fish supports powerful features like syntax highlighting, autosuggestions, and tab completions that just work, with nothing to learn or configure.

If you want to make your command line more productive, more useful, and more fun, without learning a bunch of arcane syntax and configuration options, then fish might be just what you're looking for!

To me, it is an improvement over bash in at least these areas:

  • Convenience
  • Configurability
  • Scripting Syntax
  • Platform neutrality
  • Proper Documentation

You can find it here


Fish - as it comes - includes a load of thing that potentially improve productivity in the Terminal immediately. A great access to the history of commands, as well as amazing tab-completion are to be mentionied here.

Completion is turned on by default and as you type, you’ll get (greyed out here) suggestions form your history:


Of course completion does not stop here, as fish “knows” how to complete git for instance by default:


Note that you can use the tab-key to cycle through the suggestions


It also can provide further information about the completions


and to wrap this up, after running fish_update_completions, fish completes more or less anything there is a man page for !

From where i am standing, this alone makes it well worth giving it a try!


The creators of fish have a funny approach to configurability:

Configurability is the root of all evil

Every configuration option in a program is a place where the program is too stupid to figure out for itself what the user really wants, and should be considered a failure of both the
program and the programmer who implemented it.

Nevertheless, for the most obvious things, fish comes with a nifty web-console for configuration called ‘fish_config’.

Scripting Syntax

I confess not to be a bash wizard, and i probably never will be. This is mostly because i don’t need to write scripts regularly, so it feels like a waste to wrap my head around that pesky syntax. Fish on the other hand brings an intuitive scripting language, that raises my hope of not being lost every time i’d need to script a few lines.

So even if you have never seen a fish script, you’ll be able to read this, right?

if grep fish /etc/shells
    echo Found fish
else if grep bash /etc/shells
    echo Found bash
    echo Got nothing


switch (uname)
case Linux
    echo Hi Tux!
case Darwin
    echo Hi Hexley!
case FreeBSD NetBSD DragonFly
    echo Hi Beastie!
case '*'
    echo Hi, stranger!

That’s right, no more fi or trying to remember where to put a semicolon.

Platform neutrality

Fish comes for MacOs, Windows (Cygwin, Msys2) and Linux (11 flavours pre-packaged).

Ever tried to create a tiny script in bash, because everyone in the Team/Company should benefit from it, just to find your peers complaining about bash showing a slightly different behavior on MacOS, than on Linux? Not only is the scripting language a more intuitive than bash, it’ll run consistently. That of course leaves you with the prerequisite of convincing everyone to install fish, but you know… :)

Proper Documentation in one place

I really love the docs

9 Tips what to do with a fish

Here is, what i did after installing fish. None of these steps is required or even suggested, it is just what i did to further tweak fish in order to make it more convenient for me.

Tip 1: Do /not/ make fish the default shell

Many people assume that bash or a compatible shell is the default shell. For that reason, i did not use chsh in order to make it default. Where i start sub-shells (like when using sudo or guake), i explicitly call fish. (The su function will be discussed later, see Tip 6).

Tip 2: Use fish_config

Use ‘fish_config’ to select the prompt you like and peek into key bindings and predefined functions.

Tip 3: Add fish_update_completions to your crontab

In order to be sure to leverage the full power of tab completion

Tip 4: Use the F1 Key

F1 brings up the man page of a command, and lets you continue typing after exiting the man page. Just as it should be.

Tip 5: Install re-search

In order to be able to CTRL-R through your history, you’d probably want to install re-search:

git clone https://github.com/jbonjean/re-search.git     
cd re-search ; make ; sudo cp re-search /usr/local/bin ; cp *.fish ~/.config/fish/functions 

and then create ~/.config/fish/functions/fish_user_key_bindings.fish

function fish_user_key_bindings
	bind \cr re_search

That gives you incremental search in your history and binds it to CTRL-R, similar than what you are used to from bash.

Tip 6: Put globals into ~/.config/fish/config.fish

This is where to put scripts that should fire when starting fish. The contents of mine is

# disable fishy greeting
set fish_greeting 

# define aliases
alias apt="sudo apt"
alias su="sudo /bin/su --shell=/usr/bin/fish "

Note, that the su alias explicitely asks for fish as the shell.

Tip 7: Tweak the Prompt

Skip this if you’re all lucky with the prompt you selected via fish_config.

I disliked the path abbreviations and wanted to have the git status on the right, so here’s what i did:

Create a file ~/.config/fish/functions/fish_prompt.fish

function fish_prompt --description 'Write out the prompt'
    set -l home_escaped (echo -n $HOME | sed 's/\//\\\\\//g')
    # set pwd to $PWD with the home replaced by ~
    set -l pwd (echo -n $PWD | sed "s/^$home_escaped/~/" | sed 's/ /%20/g')

	set -l color_bracket FAFAFA
	set -l color_user BBB
	set -l color_host yellow

    set_color $color_bracket
    printf '[' 

    set_color $color_user
	printf '%s' $USER

    # Show the host only for remote sessions
	if test -n "$SSH_CLIENT" -o -n "$SSH_TTY"
		set_color $color_host
		printf '@%s' (hostname)

	set_color $fish_color_cwd

	printf ' %s' $pwd
    set_color $color_bracket
	printf '] '
    set_color normal


That gives you my fav. kind of prompt, with ~ replacing home and @HOST only shown, if it is a non-local session.

Then, create a file ~/.config/fish/functions/fish_right_prompt.fish

# fish git prompt
set __fish_git_prompt_showdirtystate 'yes'
set __fish_git_prompt_showupstream 'yes'
set __fish_git_prompt_color_branch yellow

# Status Chars
set __fish_git_prompt_char_dirtystate '!'
set __fish_git_prompt_char_upstream_ahead '>'
set __fish_git_prompt_char_upstream_behind '<'
function fish_right_prompt -d "Write out the right prompt"
        printf '%s ' (__fish_git_prompt)

that will give you the git status on the right, like:

i am sure, you can figure out, what the symbols mean :)

Tip 8: Install Oh-My-Fish and z

OMF, The Fishshell Framework

curl -L https://get.oh-my.fish | fish
omf install z

I am sure, there are many gems to be discovered in the OMF repository, but i really want to point to z.

z gives you a tiny function, that lets you cd without navigating through a directory tree using your history, even if (and this is the important part) you partly know the target directory’s name.

Some example:

Tip 9: Browse the OMF repo

While all a matter of taste, i like things like sudope as well. If you found another must-have plugin, let me know…