Quick Info

Fish initialization file ~/.config/fish/

Switch between different key bindings:

  • fish_default_key_bindings to use default key bindings
  • fish_vi_key_bindings to use vi key bindings


Available scopes

  • local variable local to a block
  • global variable global to shell instance
  • universal variable universal to all shell instances + preserved across shell restart

Set/Unset Variables

set <name> [<values>]
    -l  local scope
    -g  global scope
    -U  universal scope
    -e  erase variable
    -S  show verbose info
    -x  export to ENV
    -u  unexport from ENV

Special Variables ref

$status      # exit code of last command
$pipestatus  # list of exit codes of pipe chain

$fish_pid    # pid of parent fish shell    ($$ in bash)
$last_pid    # pid of last started process ($! in bash)

$CMD_DURATION   # runtime of last command in ms


In fish all variables are lists (start with index 1, but lists can't contain lists.

set foo a b c d

echo $foo[1]      # a
echo $foo[-1]     # d
echo $foo[2..3]   # b c
echo $foo[1 3]    # a c

$ can be seen as dereference operator.

set foo a; set a 1337
echo $$foo  # outputs 1337

Cartesian product.

echo file.{h,cc}
# file.h

echo {a,b}{1,2}
# a1 b1 a2 b2

*PATH ref

Lists ending with PATH are automatically split at : when used and joined with : when quoted or exported to the environment.

set -x BLA_PATH a:b:c:d
echo $BLA_PATH           # a b c d
echo "$BLA_PATH"         # a:b:c:d          (quoted)
env | grep BLA_PATH      # BLA_PATH=a:b:c:d (env)

set FOO_PATH x y z
echo $FOO_PATH           # x y z
echo "$FOO_PATH"         # x:y:z

Command Handling

# sub-commands are not run in quotes
echo "ls output: "(ls)

I/O redirection

# 'noclobber', fail if 'log' already exists
echo foo >? log

Process substitution

Redirect output of multiple processes. Same as <(..) in bash.

diff (sort a | psub) (sort b | psub)

Control Flow

if / else

if grep foo bar
    # do sth
else if grep foobar bar
    # do sth else
    # do sth else


switch (echo foo)
case 'foo*'
    # do start with foo
case bar dudel
    # do bar and dudel
case '*'
    # do else

while Loop

while true
    echo foo

for Loop

for f in (ls)
    echo $f


Function arguments are passed via $argv list.

function fn_foo
    echo $argv


When running a command fish attempts to autoload a function. The shell looks for <cmd>.fish in the locations defined by $fish_function_path and loads the function lazily if found.

This is the preferred way over monolithically defining all functions in a startup script.


functions         # list al functions
functions foo     # describe function 'foo'
functions -e foo  # erase function 'foo'

funced foo        # edit function 'foo'
                  # '-e vim' to edit in vim

Argument parsing and completion

argparse puts options into variables of name _flag_NAME.


function moose --d "my moose fn"
    # h/help   : short / long option (boolean)
    # color    : only long option (boolean)
    # u/user=  : option with required argument, only last specified is taken
    # f/file+= : option with required argument, can be specified multiple times
    argparse h/help color= u/user= f/file=+ -- $argv
    or return

    if set -ql _flag_help
        echo "usage ..."
        return 0

    set -ql _flag_file
    and echo "file=$_flag_file | cnt:" (count $_flag_file)

    set -ql _flag_color
    and echo "color=$_flag_color"

    set -ql _flag_user
    and echo "user=$_flag_user"

# Delete all previous defined completions for 'moose'.
complete -c moose -e

# Don't complete files for command.
complete -c moose --no-files

# Help completion.
#   -n specifies a conditions. The completion is only active if the command
#      returns 0.
complete -c moose -s h -l help -n "not __fish_contains_opt -s h help" \
    --description "Print usage help and exit"

# File completion.
#   -F force complete files (overwrite --no-files).
#   -r requires argument.
complete -c moose -s f -l file -F -r \
    --description "Specify file (can be passed multiple times)"

# Color completion.
#    -a options for completion.
#    -x short for -r and --no-files (-f)
complete -c moose -x -l color -a "red blue" \
    --description "Specify a color."

# User completion.
#    -a options for completion. Call a function to generate arguments.
complete -c moose -x -s u -l user -a "(__fish_complete_users)" \
    --description "Specify a user"


The prompt is defined by the output of the fish_prompt function.

function fish_prompt
    set -l cmd_ret
    echo "> "(pwd) $cmd_ret" "

Use set_color to manipulate terminal colors and set_color -c to print the current colors.

Useful Builtins

List all builtins with builtins -n.

# history
history search <str>   # search history for <str>
history merge          # merge histories from fish sessions

# list
count $var             # count elements in list

contains /bin $PATH    # return 0 (true) 1 (false)
contains -i /bin $PATH # additionally print index on stdout

# string
string split SEP STRING

# math
math -b hex 4096       # output dec as hex
math 0x1000            # output hex as dec
math "log2(1024)"      # call functions
math -s0 7/3           # integer division (by default float)

# status
status -f              # abs path of current file


  Shift-Tab .............. tab-completion with search
  Alt-Up / Alt-Down ...... search history with token under the cursor
  Alt-l .................. list content of dir under cursor
  Alt-p .................. append '2>&1 | less;' to current cmdline
  Alt-Left / Alt - Right . prevd / nextd, walk dir history


  status print-stack-trace .. prints function stacktrace (can be used in scripts)
  breakpoint ................ halt script execution and gives shell (C-d | exit
                              to continue)