FISH-TUTORIAL(1) fish-shell FISH-TUTORIAL(1) (NAME) fish-tutorial - (WHY FISH?) fish ( bash zsh) . (Syntax Highlighting) (Autosuggestions) (Tab Completions) . ! (GETTING STARTED) fish ! : > fish Welcome to fish, the friendly interactive shell Type help for instructions on how to use fish you@hostname ~> : . <#prompt>. > . (LEARNING FISH) . unlike other shells ( ) . <>. <>. <>. (RUNNING COMMANDS) : . : > echo hello world hello world echo hello world . hello world . <#escapes> <#quotes>: > mkdir My\ Files # Makes a directory called "My Files", with a space in the name > cp ~/Some\ File 'My Files' # Copies a file called "Some File" in the home directory to "My Files" > ls "My Files" Some File (GETTING HELP) help man ( fish-language) man . help set man set . > man set set - handle shell variables Synopsis... help getting-help . (builtins) . man man ls ls . (SYNTAX HIGHLIGHTING) () . : > /bin/mkd . : > /bin/mkdir (Underline) : > cat ~/somefi somefi . fish_config <#variables- color> . () : fish_config theme choose none "none" () . : fish_config theme show fish_config . (AUTOSUGGESTIONS) : > /bin/hostname : > grep --ignore-case . : > rsync -avze ssh . myname@somelonghost.com:/some/long/path/doo/dee/doo/dee/doo (->) ctrl-f . alt- (->) . . $fish_autosuggestion_enabled 0 : set -g fish_autosuggestion_enabled 0 (TAB COMPLETIONS) . tab : > /pritab => /private/ : > ~/stuff/stab ~/stuff/script.sh (command) ~/stuff/sources/ (directory) . ( "command" "directory" ) . : > git merge prtab => git merge prompt_designer > git checkout btab builtin_list_io_merge (Branch) builtin_set_color (Branch) busted_events (Tag) ! (VARIABLES) : > echo My home directory is $HOME My home directory is /home/tutorial (Variable Substitution) (Double Quotes) (Single Quotes) : > echo "My current directory is $PWD" My current directory is /home/tutorial > echo 'My current directory is $PWD' My current directory is $PWD : set . > set name 'Mister Noodle' > echo $name Mister Noodle ( : Mister Noodle $name .) : > mkdir $name > ls Mister Noodle (bash) "Mister" "Noodle" . : "Mister Noodle" mkdir . -e --erase () : > set -e MyVariable > env | grep MyVariable (no output) <#expand-variable>. ( ) (EXPORTS - SHELL VARIABLES) . git man $PAGER ( ) . $BROWSER $LANG ( ) $PATH . . (Export) . set : --export -x. > set -x MyVariable SomeValue > env | grep MyVariable MyVariable=SomeValue --unexport -u . ! . $LANG en_US.UTF-8 . . $LANG $PATH $TERM . (Local) (Global) (Universal) - (Exported) <#variables-scope>! set -gx MyVariable SomeValue . <#variables-export>. (LISTS) set Mister Noodle . name . . $PWD . <<>> ( ) . $PATH . : > echo $PATH /usr/bin /bin /usr/sbin /sbin /usr/local/bin "PATH" (Colon) . . $PATH . set --path set --unpath . . . count : > count $PATH 5 . /usr/local/bin $PATH : > set PATH $PATH /usr/local/bin . 1 -1 : > echo $PATH /usr/bin /bin /usr/sbin /sbin /usr/local/bin > echo $PATH[1] /usr/bin > echo $PATH[-1] /usr/local/bin ("slices") : > echo $PATH[1..2] /usr/bin /bin > echo $PATH[-1..2] /usr/local/bin /sbin /usr/sbin /bin for ( ) : for val in $PATH echo "entry: $val" end # Will print: # entry: /usr/bin/ # entry: /bin # entry: /usr/sbin # entry: /sbin # entry: /usr/local/bin (Brace Expansion) <#expand-brace>. : > set mydirs /usr/bin /bin > echo $mydirs/fish # this is just like {/usr/bin,/bin}/fish /usr/bin/fish /bin/fish : > set empty # no argument > echo $empty/this_is_gone # prints an empty line . <#variables- lists>. ( ) <#cartesian-product> <#expand-variable> . (WILDCARDS) * . JPEG: > ls *.jpg lena.jpg meena.jpg santa maria.jpg : > ls l*.p* lena.png lesson.pdf ** : > ls /var/**.log /var/log/system.log /var/run/sntp.log ctrl-c . <#expand-wildcard>. (PIPES AND REDIRECTIONS) () : > echo hello world | wc 1 2 12 (stdin) (stdout) < > . (stderr) 2> . > grep fish < /etc/shells > ~/output.txt 2> ~/errors.txt &> : > make &> make_output.txt <#redirects> <#pipes> . (COMMAND SUBSTITUTIONS) . `` : > echo In (pwd), running $(uname) In /home/tutorial, running FreeBSD : > set os (uname) > echo $os Linux : > touch "testing_$(date +%s).txt" > ls *.txt testing_1360099791.txt ( space tab) (Newline) . . pkg-config . string split . > printf '%s\n' (pkg-config --libs gio-2.0) -lgio-2.0 -lgobject-2.0 -lglib-2.0 > printf '%s\n' (pkg-config --libs gio-2.0 | string split -n " ") -lgio-2.0 -lgobject-2.0 -lglib-2.0 : > echo "first line second line" > myfile > set myfile "$(cat myfile)" > printf '|%s|' $myfile |first line second line| <#expand-command-substitution>. (SEPARATING COMMANDS - SEMICOLON) . (";") . : echo fish; echo chips # or echo fish echo chips . . (EXIT STATUS) ( 0) . $status $?. > false > echo $status 1 - 0 . set --query set --query PATH 0 set --query arglbargl boogagoogoo 2 . $pipestatus [1] . <# variables-status>. [1] "stati" "status" (COMBINERS: AND, OR, NOT) && || ! : > ./configure && make && sudo make install make ./configure ( 0 ) sudo make install ./configure make . and <> or <> not <> . (Job Modifiers) . : > cp file1 file1_bak && cp file2 file2_bak; and echo "Backup successful"; or echo "Backup failed" Backup failed : cp file1 file1_bak && cp file2 file2_bak and echo "Backup successful" or echo "Backup failed" (CONDITIONALS: IF, ELSE, SWITCH) if <> else <> : if grep fish /etc/shells echo Found fish else if grep bash /etc/shells echo Found bash else echo Got nothing end ( ) test <> : if test "$fish" = "flounder" echo FLOUNDER end # or if test "$number" -gt 5 echo $number is greater than five else echo $number is five or less end # or # This test is true if the path /etc/hosts exists # - it could be a file or directory or symlink (or possibly something else). if test -e /etc/hosts echo We most likely have a hosts file else echo We do not have a hosts file end : if command -sq fish; and grep fish /etc/shells echo fish is installed and configured end begin <> end <> . switch <> : switch (uname) case Linux echo Hi Tux! case Darwin echo Hi Hexley! case FreeBSD NetBSD DragonFly echo Hi Beastie! case '*' echo Hi, stranger! end case <> (fall through) ( ) . <#syntax- conditional>. (FUNCTIONS) . << >> $1 $argv . function <> : function say_hello echo Hello $argv end say_hello # prints: Hello say_hello everybody! # prints: Hello everybody! (alias) . [2] functions <> ( !). : > functions N_, abbr, alias, bg, cd, cdh, contains_seq, dirh, dirs, disown, down-or-search, edit_command_buffer, export, fg, fish_add_path, fish_breakpoint_prompt, fish_clipboard_copy, fish_clipboard_paste, fish_config, fish_default_key_bindings, fish_default_mode_prompt, fish_git_prompt, fish_hg_prompt, fish_hybrid_key_bindings, fish_indent, fish_is_root_user, fish_job_summary, fish_key_reader, fish_md5, fish_mode_prompt, fish_npm_helper, fish_opt, fish_print_git_action, fish_print_hg_root, fish_prompt, fish_sigtrap_handler, fish_svn_prompt, fish_title, fish_update_completions, fish_vcs_prompt, fish_vi_cursor, fish_vi_key_bindings, funced, funcsave, grep, help, history, hostname, isatty, kill, la, ll, ls, man, nextd, open, popd, prevd, prompt_hostname, prompt_pwd, psub, pushd, realpath, seq, setenv, suspend, trap, type, umask, up-or-search, vared, wait functions : > functions ls function ls --description 'List contents of directory' command ls -G $argv end <#syntax-function>. [2] alias <> . abbr <> <#abbreviations>. (LOOPS) While: while true echo "Loop forever" end # Prints: # Loop forever # Loop forever # Loop forever # ctrl-c . For : for file in *.txt cp $file $file.bak end seq : for x in (seq 5) touch file_$x.txt end <#syntax-loops-and-blocks>. (PROMPT) PS1 . fish_prompt <> . fish_right_prompt <> . : > function fish_prompt; echo "New Prompt % "; end New Prompt % _ funcsave fish_prompt . ~/.config/fish/functions/fish_prompt.fish ( ). . set_color <> ANSI RGB : function fish_prompt set_color purple date "+%m/%d/%y" set_color FF0000 echo (pwd) '>' (set_color --reset) end : 02/06/13 /home/tutorial > _ : <>. fish_config fish_config prompt . $PATH $PATH . $PATH . $PATH - . /usr/local/bin /usr/sbin $PATH : > set PATH /usr/local/bin /usr/sbin $PATH /usr/local/bin $PATH : > set PATH (string match -v /usr/local/bin $PATH) $PATH <#variables-path> ( ) : > echo "$PATH" /usr/local/sbin:/usr/local/bin:/usr/bin $PATH . config.fish .profile . fish_add_path <> PATH . $fish_user_paths $PATH . /usr/local/bin $PATH : > fish_add_path /usr/local/bin : . config.fish . $fish_user_paths config.fish . (.bashrc ) (STARTUP - WHERE'S .BASHRC?) ~/.config/fish/config.fish . . config.fish : > cat ~/.config/fish/config.fish set -x PATH $PATH /sbin/ function ll ls -lh $argv end (Autoloading Functions) . .fish ~/.config/fish/conf.d/ . <# configuration>. (AUTOLOADING FUNCTIONS) ~/.config/fish/functions/ . ll ll.fish ~/.config/fish/functions : > cat ~/.config/fish/functions/ll.fish function ll ls -lh $argv end : > cat ~/.config/fish/functions/fish_prompt.fish function fish_prompt echo (pwd) "> " end funced <> funcsave <> $fish_function_path <#syntax-function- autoloading> . () (UNIVERSAL VARIABLES) - (Reboot) - . set -U : > set -U EDITOR vim : > echo $EDITOR vim <#configuration>. <# variables-universal>. (READY FOR MORE?) <#intro> gitter . (AUTHOR) fish-shell (COPYRIGHT) fish-shell 4.9 September 7, 2026 FISH-TUTORIAL(1)