FISH-LANGUAGE(1) fish-shell FISH-LANGUAGE(1) (NAME) fish-language - fish . << >> (Interactive use) <> . (SYNTAX OVERVIEW) fish . . : echo hello world echo <> . hello world . fish . . . fish . PATH . ( /home/me/code/checkers/checkers ../checkers) . : o cd <>: o ls: o man: - man ls "ls" man mv "mv" . o mv: ( ) o cp: o open <>: o less: ' ' . ( /return) - ; . - . (switch) . - . ls . -l ls . . . --help --version -i . man your-command-here . fish : (expansions) . (TERMINOLOGY) fish : o (Argument): . echo foo "foo" . o (Builtin): . . echo foo "echo" . o (Command): . . echo foo "echo" command echo foo "echo" /bin/echo . o (Function): . . o (Job): . o (Pipeline): . echo foo | grep foo . o (Redirection): . o (Switch) (Option): . . echo -n foo "-n" . (QUOTES) fish $ *. (quotes) : rm "my file.txt" my file.txt my file.txt . fish : (') (") . fish (expansion) . fish $(command) . ( ) ( \n) . . \' \\ . \" \$ \ \\ . . : grep 'enabled)$' foo.txt foo.txt enabled) ( $ grep : ). apt install "postgres-*" "postgres-" "postgres-something" . (ESCAPING CHARACTERS) . (escape sequences) . : o \a (alert / ) . o \e (escape) . o \f (form feed) . o \n (newline) . o \r (carriage return) . o \t (tab) . o \v (vertical tab) . o \xHH \XHH HH () . \x9 . . fish ASCII UTF-8 \X7f ASCII . o \ooo ooo () ASCII . \011 . \177 . o \uXXXX XXXX - . \u9 . o \UXXXXXXXX XXXXXXXX - . \U9 . U10FFFF . o \cX X . \ci . C0 : . ' ( ). (literal) . : echo \'hello world\' 'hello world' ( ) : echo 'hello world' hello world ( ). ' . : o \ ( ) . . o \$ . o \\ . o \* . o \? ( qmark-noglob ). o \~ . o \# / . o \( . o \) . o \{ . o \} . o \[ / . o \] / . o \< . o \> . o \& . o \| () . o \; - . o \" . o \' ( ) . \ <<>> ("continuation") fish ( ). / (INPUT/OUTPUT REDIRECTION) / (I/O) : o (stdin) . . o (stdout) . . o (stderr) . . (File Descriptor FD) : stdin stdout stderr. (redirection) . echo hello > output.txt echo . o . o /dev/null . o >DESTINATION . o 2>DESTINATION . [1] o ( ) >>DESTINATION_FILE . o 2>>DESTINATION_FILE . o ("clobber" ) >?DESTINATION 2>?DESTINATION . "noclobber" . DESTINATION : o . >/dev/null ("sinkhole"). o (&) &2 . . o (&-). . : . &> stdout stderr . echo hello &> all_output.txt stdout stderr all_output.txt . echo hello > all_output.txt 2>&1 . &>> stdout stderr . FD . o N N . o N N>DESTINATION . o N N>>DESTINATION_FILE . < . : # Write `foo`'s standard error (file descriptor 2) # to a file called "output.stderr": foo 2> output.stderr # if $num doesn't contain a number, # this test will be false and print an error, # so by ignoring the error we can be sure that we're dealing # with a number in the "if" block: if test "$num" -gt 2 2>/dev/null # do things with $num as a number greater than 2 else # do things if $num is <= 2 or not a number end # Save `make`s output in a file: make &>/log # Redirections stack and can be used with blocks: begin echo stdout echo stderr >&2 # <- this goes to stderr! end >/dev/null # ignore stdout, so this prints "stderr" # print all lines that include "foo" from myfile, or nothing if it doesn't exist. string match '*foo*' . . [1] fish ^DESTINATION . (feature flags) . (PIPING) (pipe / ) . . . | . : cat foo.txt | head cat foo.txt foo.txt stdout . head . FD . : make fish 2>| less fish () less . [2] &| ( |& Bash ) stdout stderr . [2] ("pager") ("paginates") . less ( !) . (COMBINING PIPES AND REDIRECTIONS) . : 1. . 2. . &N . >&2 stdout stderr . : # Make a function that prints something to stdout and stderr function print echo out echo err >&2 end : # Redirect both stderr and stdout to less print 2>&1 | less # or print &| less # Show the "out" on stderr, silence the "err" print >&2 2>/dev/null # Silence both print >/dev/null 2>&1 (JOB CONTROL) fish fish . . & . fish . . : emacs & emacs . fg <> . ctrl-z ( ^Z ) fish . fish . fg <> ( / foreground) . bg <> . jobs <> . disown <> . . bg <> . & . ;<>&| . (FUNCTIONS) fish . . : function ll ls -l $argv end ll ll . ll ls -l $argv . $argv . ls . end . ll /tmp/ ls -l /tmp/ /tmp . (alias) . (prompt) fish_prompt <> . : function fish_prompt # A simple prompt. Displays the current directory # (which fish stores in the $PWD variable) # and then a user symbol - a '' for a normal user and a '#' for root. set -l user_char '' if fish_is_root_user set user_char '#' end echo (set_color yellow)$PWD (set_color purple)$user_char end funced <> funcsave <> . . functions <> ( type <> ). function <> . (Defining aliases) . ls . --color=auto . ls : function ls command ls --color=auto $argv end : o $argv . . o command . ( ). . alias <> . - <> . alias <> . alias --save funcsave <> . abbreviations <# abbreviations> . . (Autoloading functions) . : o . o . o . $fish_function_path .fish . banana $fish_function_path banana.fish . $fish_function_path : o ~/.config/fish/functions ( XDG_CONFIG_HOME). o /etc/fish/functions ( $__fish_sysconfdir/functions). o . $__fish_user_data_dir ( ~/.local/share/fish XDG_DATA_HOME) XDG_DATA_DIRS fish/vendor_functions.d . XDG_DATA_DIRS /usr/share/fish/vendor_functions.d /usr/local/share/fish/vendor_functions.d . ~/.config/fish/functions . . (event handlers) . . . (mask) $fish_function_path /etc/fish/functions . <<>> (vendor) . pkgconfig pkg-config --variable functionsdir fish . pkgconfig . (COMMENTS) # . . : function ls # The function is called ls, # so we have to explicitly call `command ls` to avoid calling ourselves. command ls --color=auto $argv end . # . : set -gx EDITOR emacs # I don't like vim. (CONDITIONS) : if <> switch <> and <> or <> &&/||. if (The if statement) if <> (true) . . ( 0) if . : if test -e /etc/os-release cat /etc/os-release end test <> /etc/os-release . cat . (job) then . and or . : if test "$(uname)" = Linux echo I like penguins end test . $(uname) uname test = Linux . if else if else <> : if test "$number" -gt 10 echo Your number was greater than 10 else if test "$number" -gt 5 echo Your number was greater than 5 else if test "$number" -gt 1 echo Your number was greater than 1 else echo Your number was smaller or equal to 1 end not <> : # Check if the file contains the string "fish" anywhere. # This executes the `grep` command, which searches for a string, # and if it finds it returns a status of 0. # The `not` then turns 0 into 1 or anything else into 0. # The `-q` switch stops it from printing any matches. if not grep -q fish myanimals echo "You don't have fish!" else echo "You have fish!" end if : o contains <> - (if contains -- /usr/bin $PATH) o string <> - (if string match -q -- '*-' $arg) o path <> - (if path is -rf -- ~/.config/fish/config.fish) o type <> - (if type -q git) switch (The switch statement) switch <> . case <> . (wildcards) . : switch (uname) case Linux echo Hi Tux! case Darwin echo Hi Hexley! case DragonFly '*BSD' echo Hi Beastie! # this also works for FreeBSD and NetBSD case '*' echo Hi, stranger! end (fallthrough) - case switch . (and / or / && / ||) (Combiners) . and <> && or <> || . : # $XDG_CONFIG_HOME is a standard place to store configuration. # If it's not set applications should use ~/.config. set -q XDG_CONFIG_HOME; and set -l configdir $XDG_CONFIG_HOME or set -l configdir ~/.config (lazy evaluation) - . : if sleep 2; and false echo 'How did I get here? This should be impossible' end : if false; and sleep 2 echo 'How did I get here? This should be impossible' end sleep . : if command -sq foo; and foo <> foo ! . : test -e /etc/my.config or echo "OH NO WE NEED A CONFIG FILE" and return 1 test return 1 ! test -e /etc/my.config $status 0 echo $status 0 return 1 $status 0 . if . : if not test -e /etc/my.config echo "OH NO WE NEED A CONFIG FILE" return 1 end (LOOPS AND BLOCKS) while <> for <> . while if : while true echo Still running sleep 1 end <> . ctrl-c . for for C: for file in * echo file: $file end . in : set moreanimals bird fox for animal in {cat,}fish dog $moreanimals echo I like the $animal end seq : for i in (seq 1 5) echo $i end break <> continue <> . ( ) : while read -l line echo line: $line end < file begin <> : begin set -l foo bar # this variable will only be available in this block! end (PARAMETER EXPANSION) . : o (Wildcards) - *.jpg o - $HOME o - $(cat /path/to/file) o - {/usr,}/bin o () ~ - ~/bin . . . (Wildcards ("Globbing")) * ? (wildcard) . o * ( ) / . o ** ( ) . ** . o ? / . qmark-noglob ? . . <<1>> <<5>> <<12>> . ( ) . . ( ) .. ( ) . : o a* <> . o ** . o ~/.* (dotfiles) . $status . bash shopt -s failglob . set <> path <> overrides count <> for <>. ( ) shopt -s nullglob . : # List the .foo files, or warns if there aren't any. ls *.foo # List the .foo files, if any. set foos *.foo if count $foos >/dev/null ls $foos end bash apt install : apt install "ncurses-*" (Variable expansion) << >> . ($) . : echo $HOME $HOME echo <> . $HOME . set <> : set my_directory /home/cooluser/mystuff ls $my_directory # shows the contents of /home/cooluser/mystuff . : echo $nonexistentvariable # Prints no output. : set WORD cat echo The plural of $WORD is "$WORD"s # Prints "The plural of cat is cats" because $WORD is set to "cat". echo The plural of $WORD is {$WORD}s # ditto $WORDs . {$WORD} . $WORD <> . $WORD ( set WORD "") <> . . (Quoting variables) . ("") . . . (space) (path variable) (:) [3]. - set <> : set foo 1 2 3 # a variable with three elements rm $foo # runs the equivalent of `rm 1 2 3` - trying to delete three files: 1, 2 and 3. rm "$foo" # runs `rm '1 2 3'` - trying to delete one file called '1 2 3' set foo # an empty variable rm $foo # runs `rm` without arguments rm "$foo" # runs the equivalent of `rm ''` set foo "1 2 3" rm $foo # runs the equivalent of `rm '1 2 3'` - trying to delete one file rm "$foo" # same thing << >> (Word Splitting) . bash: foo="1 2 3" rm $foo # runs the equivalent of `rm 1 2 3` rm "$foo" # runs the equivalent of `rm '1 2 3'` . . . . . . . test <> : set -l foo one two three test -n $foo # prints an error that it got too many arguments, because it was executed like test -n one two three test -n "$foo" # works, because it was executed like test -n "one two three" [3] bash zsh $IFS ( ) . (Dereferencing variables) $ <<>> ( * C C++) : set foo a b c set a 10; set b 20; set c 30 for i in (seq (count $$foo)) echo $$foo[$i] end # Output is: # 10 # 20 # 30 $$foo[$i] << $foo[$i] >>. : function print_var for arg in $argv echo Variable $arg is $$arg end end set -g foo 1 2 3 set -g bar a b c print_var foo bar # prints "Variable foo is 1 2 3" and "Variable bar is a b c" (universal) (exported) . . $foo <> . (slices) . $$foo[5] $foo $foo . $$foo[1..-1][5] ( $foo ). : set listone 1 2 3 set listtwo 4 5 6 set var listone listtwo echo $$var # Output is 1 2 3 4 5 6 echo $$var[1] # Output is 1 2 3 echo $$var[2][3] # $var[2] is listtwo, third element of that is 6, output is 6 echo $$var[..][2] # The second element of every variable, so output is 2 5 (Variables as command) . > set -g EDITOR emacs > $EDITOR foo # opens emacs, possibly the GUI version : > set EDITOR emacs -nw > $EDITOR foo # opens emacs in the terminal even if the GUI is installed > set EDITOR "emacs -nw" > $EDITOR foo # tries to find a command called "emacs -nw" - . set if $if if set cmd command command <> $cmd -q foo . (Command substitution) . : echo $(pwd) pwd <> ( <> ) echo <> . (pwd) . . $IFS [4] (newline) . : echo "$(pwd)" . string split string split0 <> . echo (pwd). (echo "(pwd)" (pwd) ). status set <> ( if set -l (something) something ). (slices) . : # Outputs 'image.png'. echo (basename image.jpg .jpg).png # Convert all JPEG files in the current directory to the # PNG format using the 'convert' program. for i in *.jpg; convert $i (basename $i .jpg).png; end # Set the ``data`` variable to the contents of 'data.txt' # without splitting it into a list. set data "$(cat data.txt)" # Set ``$data`` to the contents of data, splitting on NUL-bytes. set data (cat data | string split0) . : grep fish myanimallist1 | wc -l << >> (process substitution) . foo <(bar) <(baz) psub <> : # Compare only the lines containing "fish" in two files: diff -u (grep fish myanimallist1 | psub) (grep fish myanimallist2 | psub) . (1 GiB) . ( - ) $status 122 . . fish_read_limit ( 0 ). read <> . [4] : $IFS . string split <> . (Brace expansion) . . . : > echo input.{c,h,txt} input.c input.h input.txt # Move all files with the suffix '.c' or '.h' to the subdirectory src. > mv *.{c,h} src/ # Make a copy of `file` at `file.bak`. > cp file{,.bak} > set -l dogs hot cool cute "good " > echo {$dogs}dog hotdog cooldog cutedog good dog <<,>> : # This {} isn't special > echo foo-{} foo-{} # This passes "HEAD@{2}" to git > git reset --hard HEAD@{2} > echo {{a,b}} {a} {b} # because the inner brace pair is expanded, but the outer isn't. ( ): > echo foo-{$undefinedvar} # Output is an empty line, like a bare `echo`. : > echo {,,/usr}/bin /bin /bin /usr/bin <<,>> . (compound statement) : > {echo hello, && echo world} hello, world (Combining lists) : >_ set -l foo x y z >_ echo 1$foo # Any element of $foo is combined with the "1": 1x 1y 1z >_ echo {good,bad}" apples" # Any element of the {} is combined with the " apples": good apples bad apples # Or we can mix the two: >_ echo {good,bad}" "$foo good x bad x good y bad y good z bad z . - : >_ set -l a x y z; set -l b 1 2 3 >_ echo $a$b # same as {x,y,z}{1,2,3} x1 y1 z1 x2 y2 z2 x3 y3 z3 ! >_ set -l c # <- this list is empty! >_ echo {$c}word # Output is an empty line - the "word" part is gone . PATH : for file in $PATH/* PATH . PATH . . - echo "$c"word. . : >_ set b 1 2 3 >_ echo (echo x)$b x1 x2 x3 >_ echo (printf '%s' '')banana # the printf prints nothing, so this is nothing times "banana", # which is nothing. >_ echo (printf '%s\n' '')banana # the printf prints a newline, # so the command substitution expands to an empty string, # so this is `''banana` banana >_ echo "$(printf '%s' '')"banana # quotes mean this is one argument, the banana stays (Slices) ( ) . () : # Make $var a list of four elements set var one two three four # Print the second: echo $var[2] # prints "two" # or print the first three: echo $var[1..3] # prints "one two three" a..b ( <> <> ). a b ( a a+1 a+2 ... b) b a . - -1 -2 . (clamp) . 2..16 . 2..-2 2..-16 . -2..1 -16..2 . . . -1 . . : echo (seq 10)[1 2 3] # Prints: 1 2 3 # Limit the command substitution output echo (seq 10)[2..5] # Uses elements from 2 to 5 # Output is: 2 3 4 5 echo (seq 10)[7..] # Prints: 7 8 9 10 # Use overlapping ranges: echo (seq 10)[2..5 1..3] # Takes elements from 2 to 5 and then elements from 1 to 3 # Output is: 2 3 4 5 1 2 3 # Reverse output echo (seq 10)[-1..1] # Uses elements from the last output line to # the first one in reverse direction # Output is: 10 9 8 7 6 5 4 3 2 1 # The command substitution has only one line, # so these will result in empty output: echo (echo one)[2..-1] echo (echo one)[-3..1] : # Reverse path variable set PATH $PATH[-1..1] # or set PATH[-1..1] $PATH # Use only n last items of the PATH set n -3 echo $PATH[$n..-1] : set index 2 set letters a b c d echo $letters[$index] # returns 'b' : echo (seq 5)[$index] # This won't work set sequence (seq 5) # It needs to be written on two lines like this. echo $sequence[$index] # returns '2' $ ($$name) : > set -l list 1 2 3 4 5 > set -l name list > echo $$name[1] 1 2 3 4 5 > echo $$name[1..-1][1..3] # or $$name[1][1..3], since $name only has one element. 1 2 3 (Home directory expansion) ~ . ~ : ls ~/Music # lists my music directory echo ~root # prints root's home directory, probably "/root" (Combining different expansions) . . : o o o o ( ) . : <> <> echo a(ls){1,2,3} abar1 abar2 abar3 afoo1 afoo2 afoo3 . (TABLE OF OPERATORS) : +-------------+--------------------------------------------+---------------------+ | | | | +-------------+--------------------------------------------+---------------------+ |$ | | echo $foo | +-------------+--------------------------------------------+---------------------+ |$() () | | cat (grep foo bar) | | | | cat $(grep | | | | foo bar) | +-------------+--------------------------------------------+---------------------+ |< > | | git shortlog -nse . | | | command > file | > authors | +-------------+--------------------------------------------+---------------------+ || | () | foo | grep bar | | | | | grep baz | | | | | +-------------+--------------------------------------------+---------------------+ |; | | command1; command2 | | | | | +-------------+--------------------------------------------+---------------------+ |& | | sleep 5m & | | | | | +-------------+--------------------------------------------+---------------------+ |{} | | ls {/usr,}/bin | +-------------+--------------------------------------------+---------------------+ |&& || | | mkdir foo && cd foo | | | | rm foo || | | | | exit | +-------------+--------------------------------------------+---------------------+ |* ** | | cat *.fish | | | | count **.jpg | +-------------+--------------------------------------------+---------------------+ |\\ | (Escaping) | echo foo\nbar | | | | echo \$foo | +-------------+--------------------------------------------+---------------------+ |'' "" | | rm "file with | | | | spaces" echo | | | | '$foo' | +-------------+--------------------------------------------+---------------------+ |~ | | ls ~/ ls | | | | ~root/ | +-------------+--------------------------------------------+---------------------+ |# | | echo Hello # this | | | | isn't printed | +-------------+--------------------------------------------+---------------------+ (SHELL VARIABLES) . <<>> (exported) . << >> (environment variable) . set <> . (underscore) . . : smurf_color blue set smurf_color blue . . : set smurf_color blue echo Smurfs are usually $smurf_color set pants_color red echo Papa smurf, who is $smurf_color, wears $pants_color pants set $ . (Variable Scope) (scope) . (global) (local) : # This variable is global, we can use it everywhere. set --global name Patrick # This variable is local, it will not be visible in a function we call from here. set --local place "at the Krusty Krab" function local # This can find $name, but not $place echo Hello this is $name $place # This variable is local, it will not be available # outside of this function set --local instrument mayonnaise echo My favorite instrument is $instrument # This creates a local $name, and won't touch the global one set --local name Spongebob echo My best friend is $name end local # Will print: # Hello this is Patrick # My favorite instrument is mayonnaise # My best friend is Spongebob echo $name, I am $place and my instrument is $instrument # Will print: # Patrick, I am at the Krusty Krab and my instrument is : (universal) (global) (function) (local). o (Universal) . . o (Global) . set -e . o (Function) . ( ). . o (Local) . for while if function begin switch end . . -U --universal -g --global -f --function -l --local . : o . . o . . o . . . . : . : function something set -l file /path/to/my/file if not test -e "$file" set file /path/to/my/otherfile end end # or function something if test -e /path/to/my/file set -f file /path/to/my/file else set -f file /path/to/my/otherfile end end config.fish : # Don't shorten the working directory in the prompt set -g fish_prompt_pwd_dir_length 0 # Set my preferred cursor style: function setcursors set -g fish_cursor_default block set -g fish_cursor_insert line set -g fish_cursor_visual underscore end # Set my language set -gx LANG de_DE.UTF-8 : function test-scopes begin # This is a nice local scope where all variables will die set -l pirate 'There be treasure in them thar hills' set -f captain Space, the final frontier # If no variable of that name was defined, it is function-local. set gnu "In the beginning there was nothing, which exploded" end # This will not output anything, since the pirate was local echo $pirate # This will output the good Captain's speech # since $captain had function-scope. echo $captain # This will output Sir Terry's wisdom. echo $gnu end : function shiver set phrase 'Shiver me timbers' end function avast set --local phrase 'Avast, mateys' # Calling the shiver function here can not # change any variables in the local scope # so phrase remains as we set it here. shiver echo $phrase end avast # Outputs "Avast, mateys" . . . . (Overriding variables for a single command) (override) <> : # Call git status on another directory # (can also be done via `git -C somerepo status`) GIT_DIR=somerepo git status : set foo banana foo=gagaga echo $foo # prints gagaga, while in other shells it might print "banana" : # Call bash with a reasonable default path. PATH={/usr,}/{s,}bin bash (glob): # Run vlc on all mp3 files in the current directory # If no file exists it will still be run with no arguments mp3s=*.mp3 vlc $mp3s ( ) . . . . (Universal Variables) . . .config/fish/fish_variables . . . config.fish . . (Exporting variables) (export) . ( PAGER GOPATH) ( PATH LANGUAGE) . . << >> . - ( ) . PATH (locale) . -x --export -u --unexport . - . . . : set -gx ANDROID_HOME ~/.android # /opt/android-sdk set -gx CDPATH . ~ (test -e ~/Videos; and echo ~/Videos) set -gx EDITOR emacs -nw set -gx GOPATH ~/dev/go set -gx GTK2_RC_FILES "$XDG_CONFIG_HOME/gtk-2.0/gtkrc" set -gx LESSHISTFILE "-" : (exporting) . (global) . . . (Lists) ( <<>>) : > set mylist first second third > printf '%s\n' $mylist # prints each element on its own line first second third () : echo $PATH[3] . seq (seq 5 ). ( ). . for : for i in $PATH echo $i is in the path end PATH . smurf blue small : set smurf blue small : # Set smurf to be a list with the elements 'blue' and 'small' set smurf blue small # Change the second element of smurf to 'evil' set smurf[2] evil # Erase the first element set -e smurf[1] # Output 'evil' echo $smurf . -1 : > set fruit apple orange banana > echo $fruit[-1] banana > echo $fruit[-2..-1] orange banana > echo $fruit[-1..1] # reverses the list banana orange apple (slices) . - . (path variable) : > set -x smurf blue small > set -x smurf_PATH forest mushroom > env | grep smurf smurf=blue small smurf_PATH=forest:mushroom PATH ( PATH CDPATH MANPATH) . . count <> contains <> : > count $smurf 2 > contains blue $smurf # blue was found, so it exits with status 0 # (without printing anything) > echo $status 0 > contains -i blue $smurf 1 : set -l grep_args -r "my string" grep $grep_args . # will run the same as `grep -r "my string"` . << >> (word splitting) - . (Argument Handling) $argv . : function myfunction echo $argv[1] echo $argv[3] end : > myfunction first second third first third > myfunction apple cucumber banana apple banana (positional arguments) $argv . (-h ls -lah) (--help) (--color=auto --position anywhere complete -C"git ") -- . . argparse <> $argv . : function mybetterfunction # We tell argparse about -h/--help and -s/--second # - these are short and long forms of the same option. # The "--" here is mandatory, # it tells it from where to read the arguments. argparse h/help s/second -- $argv # exit if argparse failed because # it found an option it didn't recognize # - it will print an error or return # If -h or --help is given, we print a little help text and return if set -ql _flag_help echo "mybetterfunction [-h|--help] [-s|--second] [ARGUMENT ...]" return 0 end # If -s or --second is given, we print the second argument, # not the first and third. # (this is also available as _flag_s because of the short version) if set -ql _flag_second echo $argv[2] else echo $argv[1] echo $argv[3] end end $argv $argv[2] : > mybetterfunction first -s second third second argparse argparse <> . PATH (PATH variables) (Path variables) PATH CDPATH MANPATH PYTHONPATH LANGUAGE ( <>) . <> ( ) . PATH . set MYPATH 1 2 3 echo "$MYPATH" # 1:2:3 set MYPATH "$MYPATH:4:5" echo $MYPATH # 1 2 3 4 5 echo "$MYPATH" # 1:2:3:4:5 set -x MYPATH 1 2 3 1:2:3 . > set -gx MYPATH /bin /usr/bin /sbin > env | grep MYPATH MYPATH=/bin:/usr/bin:/sbin . PATH . : . --path --unpath set . (Special variables) . PATH . . CDPATH cd <> . Locale Variables LANG LC_ALL LC_MESSAGES LC_NUMERIC LC_TIME . <#status- language>. Color variables fish_color fish_pager_color . <# variables-color>. fish_term24bit 0 (true-color) RGB ( fish_term256 0 ) . set_color <> . 1 0 . fish_term256 fish_term24bit 0 RGB . 0 set_color <> set_color ff0000 red . fish_ambiguous_width (ambiguous-width) . ( ) 1 2 . fish_emoji_width . . ( <<>>) . 2 . fish_autosuggestion_enabled autosuggestions <#autosuggestions> . 0 . . fish_transient_prompt 1 --final-rendering (scrollback) . (transient prompts) <#transient-prompt>. fish_handle_reflow . (reflow) . 1 . fish_key_bindings <# editor>. fish_escape_delay_ms ( ) Escape Escape (escape sequence) . 30 . Escape Alt Alt+character . bind <#cmd-bind- escape>. fish_sequence_key_delay_ms . \cx\ce ctrl-e ctrl-x . ctrl-x ( ). <#interactive-key- sequences>. fish_complete_path . . fish_cursor_selection_mode ( <#killring>). fish_function_path . . fish_greeting . ( funced <> ). fish_history . . <> . ( ). fish_trace set -x . --debug-output FISH_DEBUG_OUTPUT . (stderr) . all . FISH_DEBUG fish --debug. FISH_DEBUG_OUTPUT . fish_user_paths PATH . (universal) . umask . umask umask <> . umask . SHELL_PROMPT_PREFIX . run0 systemd . SHELL_PROMPT_SUFFIX . run0 systemd . SHELL_WELCOME . run0 . BROWSER . . . set . _ ( status current-command ). argv . argv fish myscript.fish foo bar. . argv_opts argparse <> . . CMD_DURATION . COLUMNS and LINES . . 80x24 . . fish_kill_signal 0 . fish_killring (kill ring) <#killring>. fish_read_limit read <> . fish_pid (PID) . fish_terminal_color_theme light dark unknown <#term-compat-query- background-color>. status terminal <#status- terminal> . --on-variable <#syntax-highlighting> . light dark <#fish- config-theme-files>. history . HOME . . hostname (hostname) . IFS read <> . . . last_pid (PID) . PWD . pipestatus . . SHLVL . . status . . status_generation <<>> $status. ( ). USER . . EUID . . version ( FISH_VERSION ). (CMD_DURATION ). . __fish . . (The status variable) (exit status) ( ) . . . status . : o 0 . o 1 . o 121 . o 123 . o 124 . o 125 . o 126 . o 127 . . not <> ( !) . 0 1 0 . $pipestatus status . not <> $status $pipestatus . : not cat file | grep -q fish echo status is: $status pipestatus is $pipestatus $status grep 0 not ( 1 0 ). $pipestatus cat ( ) grep . cat grep $status not 1 $pipestatus 0 0 . . . : cat file1 file2 | head -n 50 cat <> <> head . : > cat file1 file2 | head -n 50 # 50 lines of output > echo $pipestatus 141 0 <<141>> cat (128 + 13 == 141) SIGPIPE . fish_kill_signal . head cat . cat SIGPIPE pipestatus <<0 0>> . . <> . (Locale Variables) (locale) . . : LANG . . UTF-8 . C POSIX. LANG LC_ALL . LANG . en_US.UTF-8 de_AT.UTF-8 . locale locale -a . LANGUAGE LC_MESSAGES . (PATH variable) GNU gettext . ( zh) . zh_CN zh_TW . GNU gettext <<>> . zh_TW:zh zh_TW zh . zh_TW zh zh_TW LANGUAGE zh_TW . _ () <>. LC_ALL LANG LC_* . LC_ALL . LC_MESSAGES _ () <>. LC_NUMERIC <>. LC_TIME . history <#history-show-time>. (BUILTIN COMMANDS) . << >> (builtins) . : o - cd <> set <> . o string <> math <> count <> path <> . o status <> . o printf <> echo <> . o test <> . o argparse <> . o source <> ( ) eval <> . o random <> . o read <> . builtin -n . <>. --help . (COMMAND LOOKUP) . / . / : 1. : o . o <<.fish>> fish_function_path ( ). o . 2. . 3. PATH : o () . o ( #! #!/bin/sh #!/usr/bin/python) . o /bin/sh . fish_command_not_found <> status 127 . type <> : > type --short --all echo echo is a builtin echo is /usr/bin/echo (QUERYING FOR USER INPUT) . read <> . . : function show_files # This will glob on all arguments. Any non-directories will be ignored. set -l files $argv/* # If there are more than 5 files if test (count $files) -gt 5 # and both stdin (for reading input) # and stdout (for writing the prompt) # are terminals and isatty stdin and isatty stdout # Keep asking until we get a valid response while read --nchars 1 -l response --prompt-str="Are you sure? (y/n)" or return 1 # if the read was aborted with ctrl-c/ctrl-d switch $response case y Y echo Okay # We break out of the while and go on with the function break case n N # We return from the function without printing echo Not showing return 1 case '*' # We go through the while loop and ask again echo Not valid input continue end end end # And now we print the files printf '%s\n' $files end show_files / Y/y N/n . show_files / | cat . show_files . . (SHELL VARIABLE AND FUNCTION NAMES) ( identifiers) : o . . . o . (<<->>) (<>) . . if set . o ( bind -m abc ...) . . <> ( ) (NULL) ( ). (CONFIGURATION FILES) . . ~/.config/fish/config.fish ( $XDG_CONFIG_HOME/fish/config.fish). : o ( *.fish) : o $__fish_config_dir/conf.d ( ~/.config/fish/conf.d/) o $__fish_sysconf_dir/conf.d ( /etc/fish/conf.d/) o : o $__fish_user_data_dir ( ~/.local/share/fish XDG_DATA_HOME) o fish/vendor_conf.d $XDG_DATA_DIRS ( /usr/share/fish/vendor_conf.d /usr/local/share/fish/vendor_conf.d) $__fish_vendor_confdirs . . . ( ) ( <<01>> <<2>> ). o - /etc/profile - $__fish_sysconf_dir ( /etc/fish/config.fish). o ~/.config/fish/config.fish ( XDG_CONFIG_HOME $__fish_config_dir). ~/.config/fish/config.fish . . . status --is-interactive . (login shell) status --is-login . . . . . <<>> (vendor) . pkg-config : pkg-config --variable confdir fish. __fish_build_paths.fish . . (FUTURE FEATURE FLAGS) . (opt-in) (opt-out) . status features : > status features stderr-nocaret on 3.0 ^ no longer redirects stderr qmark-noglob on 3.0 ? no longer globs regex-easyesc on 3.1 string replace -r needs fewer \\'s ampersand-nobg-in-token on 3.4 & only backgrounds if followed by a separating character remove-percent-self off 4.0 %self is no longer expanded (use $fish_pid) test-require-arg off 4.0 builtin test requires an argument mark-prompt on 4.0 write OSC 133 prompt markers to the terminal ignore-terminfo on 4.1 do not look up $TERM in terminfo database query-term on 4.1 query the TTY to enable extra functionality omit-term-workarounds off 4.3 skip workarounds for incompatible terminals : o stderr-nocaret . . . no-stderr-nocaret . ^ stderr . 2> . o qmark-noglob . ( . ). ? . * ( ) find . o regex-easyesc . ( . ). string replace -r . string replace -ra '([ab])' '\\\\\\\\$1' '\\\\$1' . string replace . o ampersand-nobg-in-token . ( . ). & URL . & . fish_indent . o remove-percent-self %self . . . pid fish_pid . o test-require-arg test <> (test "string"). . . test -n "string" . test <# debugging-fish> <> fish --debug=deprecated-test . o mark-prompt OSC 133 . o ignore-terminfo . . . $TERM terminfo . o query-term . <#term-compat-cursor-position- report>. () set -Ua fish_features no-query-term . o omit-term-workarounds . . : > fish --features qmark-noglob,regex-easyesc : > set -U fish_features regex-easyesc qmark-noglob (universal) (exported) . 3.0 <> <> . all . no- . ?: set -Ua fish_features no-qmark-noglob (EVENT HANDLERS) (event handler) . : o o (job) o o : WINCH : function my_signal_handler --on-signal WINCH echo Got WINCH signal! end --on-event : o fish_prompt . o fish_preexec . . . o fish_posterror . . o fish_postexec . . . o fish_exit . o fish_cancel . o fish_focus_in . o fish_focus_out . emit <> . : function handler --on-event imdone echo generator is done $argv end function generator sleep 1 # The "imdone" is the name of the event # the rest is the arguments to pass to the handler emit imdone with $argv end . source <> . . function <> . (DEBUGGING FISH SCRIPTS) . ( ). printf <> set <> . status print-stack-trace <> (breakpoint) . exit <> ctrl-d . breakpoint <> . TRAP TRAP (kill -s TRAP ). : funced ( ) / . fish_trace fish_trace=1 fish_prompt fish_prompt <> . (Profiling fish scripts) fish --profile /path/to/profile.log . . : > fish --profile /tmp/sleep.prof -ic 'sleep 3s' > cat /tmp/sleep.prof Time Sum Command 3003419 3003419 > sleep 3s ( ) . . sort -nk2 /path/to/logfile . --profile-startup /path/to/logfile . fish <> . (AUTHORS) (fish-shell developers) (COPYRIGHT) (fish-shell developers) 4.9 September 7, 2026 FISH-LANGUAGE(1)