Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
FISH-FOR-BASH-USERS(1)		  fish-shell		FISH-FOR-BASH-USERS(1)

NAME
       fish-for-bash-users - A quick fish primer for those coming from bash

       This  is	 to  give  you a quick overview	if you come from bash (or to a
       lesser extent other shells like zsh or ksh) and want to know  how  fish
       differs.	Fish is	intentionally not POSIX-compatible and as such some of
       the things you are used to work differently.

       Many things are similar - they both fundamentally  expand  commandlines
       to  execute  commands,  have pipes, redirections, variables, globs, use
       command output in various ways. This document is	there to quickly  show
       you the differences.

COMMAND	SUBSTITUTIONS
       Fish  spells  command  substitutions as (command) instead of $(command)
       (or `command`).

       In addition, it only splits them	on newlines instead of	$IFS.  If  you
       want  to	 split	on  something else, use	string split, string split0 or
       string collect. If those	are used as the	last command in	a command sub-
       stitution the splits they create	are carried over. So:

	  for i	in (find . -print0 | string split0)

       will correctly handle all possible filenames.

VARIABLES
       Fish  sets and erases variables with set	instead	of VAR=VAL and declare
       and unset and export. set takes options to determine the	scope and  ex-
       portedness of a variable:

	  # Define $PAGER global and exported, so this is like ``export	PAGER=less``
	  set -gx PAGER	less

	  # Define $alocalvariable only	locally	- like ``local alocalvariable=foo``
	  set -l alocalvariable	foo

       or to erase variables:

	  set -e PAGER

       VAR=VAL statements are available	as environment overrides:

	  PAGER=cat git	log

       Fish does not perform word splitting. Once a variable has been set to a
       value, that value stays as it is, so double-quoting variable expansions
       isn't the necessity it is in bash. [1]

       For instance, here's bash

	  > foo="bar baz"
	  > printf '"%s"\n' $foo # will	print two lines, because we didn't double-quote, so the	variable is split
	  "bar"
	  "baz"

       And here	is fish:

	  > set	foo "bar baz"
	  > printf '"%s"\n' $foo # foo was set as one element, so it will be passed as one element, so this is one line
	  "bar baz"

       All  variables  are "arrays" (we	use the	term "lists"), and expanding a
       variable	expands	to all its elements, with each element as its own  ar-
       gument (like bash's "${var[@]}":

	  > set	var "foo bar" banana
	  > printf %s\n	$var
	  foo bar
	  banana

       Specific	elements of a list can be selected:

	  echo $list[5..7]

       [1]  zsh	  also	does  not  perform  word  splitting  by	 default  (the
	    SH_WORD_SPLIT option controls this)

WILDCARDS (GLOBS)
       Fish only supports the *	and ** glob (and the deprecated	? glob). If  a
       glob doesn't match it fails the command (like with bash's failglob) un-
       less the	command	is for,	set or count or	the glob is used with an envi-
       ronment	override  (VAR=* command), in which case it expands to nothing
       (like with bash's nullglob option).

       Globbing	doesn't	happen on expanded variables, so:

	  set foo "*"
	  echo $foo

       will not	match any files.

       There are no options to control globbing	 so  it	 always	 behaves  like
       that.

QUOTING
       Fish  has two quoting styles: ""	and ''.	Variables are expanded in dou-
       ble-quotes, nothing is expanded in single-quotes.

       There is	no $'',	instead	the sequences that would transform are	trans-
       formed when unquoted:

	  > echo a\nb
	  a
	  b

STRING MANIPULATION
       Fish  does  not have ${foo%bar},	${foo#bar} and ${foo/bar/baz}. Instead
       string manipulation is done by the string builtin.

SPECIAL	VARIABLES
       Some bash variables and their closest fish equivalent:

       o $*, $@, $1 and	so on: $argv

       o $?: $status

       o $$: $fish_pid

       o $#: No	variable, instead use count $argv

       o $!: $last_pid

       o $0: status filename

       o $-: Mostly status is-interactive and status is-login

PROCESS	SUBSTITUTION
       Instead of <(command) fish uses (command	| psub). There is  no  equiva-
       lent to >(command).

       Note that both of these are bashisms, and most things can easily	be ex-
       pressed without.	E.g. instead of:

	  source (command | psub)

       just use:

	  command | source

       as fish's source	can read from stdin.

HEREDOCS
       Fish does not have <<EOF	"heredocs". Instead of:

	  cat <<EOF
	  some string
	  some more string
	  EOF

       use:

	  printf %s\n "some string" "some more string"

       or:

	  echo "some string
	  some more string"

       Quotes are followed across newlines.

TEST (TEST, [, [[)
       Fish has	a POSIX-compatible test	or [ builtin. There is no [[ and  test
       does  not  accept  == as	a synonym for =. It can	compare	floating point
       numbers,	however.

       set -q can be used to determine if a variable exists or has  a  certain
       number of elements (set -q foo[2]).

ARITHMETIC EXPANSION
       Fish  does  not have $((i+1)) arithmetic	expansion, computation is han-
       dled by math:

	  math $i + 1

       It can handle floating point numbers:

	  > math 5 / 2
	  2.5

PROMPTS
       Fish does not use the $PS1, $PS2	 and  so  on  variables.  Instead  the
       prompt	is   the   output   of	the  fish_prompt  function,  plus  the
       fish_mode_prompt	  function   if	  vi-mode   is	 enabled    and	   the
       fish_right_prompt function for the right	prompt.

       As an example, here's a relatively simple bash prompt:

	  # <$HOSTNAME>	<$PWD in blue> <Prompt Sign in Yellow> <Rest in	default	light white>
	  export PS1='\h\[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\e[m\] '

       and a rough fish	equivalent:

	  function fish_prompt
	      set -l prompt_symbol '$'
	      fish_is_root_user; and set prompt_symbol '#'

	      echo -s $hostname	(set_color blue) (prompt_pwd) \
	      (set_color yellow) $prompt_symbol	(set_color normal)
	  end

       This shows a few	differences:

       o Fish provides set_color to color text.	It can use the 16 named	colors
	 and also RGB sequences	(so you	could also use set_color 5555FF)

       o Instead of introducing	specific escapes like \h for the hostname, the
	 prompt	is simply a function, so you can use variables like $hostname.

       o Fish  offers  helper  functions for adding things to the prompt, like
	 fish_vcs_prompt for adding a display for common version control  sys-
	 tems  (git,  mercurial,  svn)	and prompt_pwd for showing a shortened
	 $PWD (the user's home directory becomes ~ and any path	 component  is
	 shortened).

       The default prompt is reasonably	full-featured and its code can be read
       via type	fish_prompt.

       Fish does not have $PS2 for continuation	lines, instead it  leaves  the
       lines indented to show that the commandline isn't complete yet.

BLOCKS AND LOOPS
       Fish's blocking constructs look a little	different. They	all start with
       a word, end in end and don't have a second starting word:

	  for i	in 1 2 3; do
	     echo $i
	  done

	  # becomes

	  for i	in 1 2 3
	     echo $i
	  end

	  while	true; do
	     echo Weeee
	  done

	  # becomes

	  while	true
	     echo Weeeeeee
	  end

	  {
	     echo Hello
	  }

	  # becomes

	  begin
	     echo Hello
	  end

	  if true; then
	     echo Yes I	am true
	  else
	     echo "How is true not true?"
	  fi

	  # becomes

	  if true
	     echo Yes I	am true
	  else
	     echo "How is true not true?"
	  end

	  foo()	{
	     echo foo
	  }

	  # becomes

	  function foo
	      echo foo
	  end

	  # (note that bash specifically allows	the word "function" as an extension, but POSIX only specifies the form without,	so it's	more compatible	to just	use the	form without)

       Fish does not have an until. Use	while not or while !.

BUILTINS AND OTHER COMMANDS
       By now it has become apparent that fish puts much more of  a  focus  on
       its  builtins and external commands rather than its syntax. So here are
       some helpful builtins and their rough equivalent	in bash:

       o string	- this replaces	most of	the string transformation (${i%foo} et
	 al) and can also be used instead of grep and sed and such.

       o math -	this replaces $((i + 1)) arithmetic and	can also do floats and
	 some simple functions (sine and friends).

       o argparse - this can handle a script's option parsing, for which  bash
	 would probably	use getopt (zsh	provides zparseopts).

       o count	can  be	used to	count things and therefore replaces $# and can
	 be used instead of wc.

       o status	provides information about the shell status, e.g. if it's  in-
	 teractive  or	what  the  current linenumber is. This replaces	$- and
	 $BASH_LINENO and other	variables.

       o seq(1)	can be used as a replacement for {1..10} range	expansion.  If
	 your OS doesn't ship a	seq fish includes a replacement	function.

AUTHOR
       fish-shell developers

COPYRIGHT
       2020, fish-shell	developers

3.2				 Aug 28, 2021		FISH-FOR-BASH-USERS(1)

NAME | COMMAND SUBSTITUTIONS | VARIABLES | WILDCARDS (GLOBS) | QUOTING | STRING MANIPULATION | SPECIAL VARIABLES | PROCESS SUBSTITUTION | HEREDOCS | TEST (TEST, [, [[) | ARITHMETIC EXPANSION | PROMPTS | BLOCKS AND LOOPS | BUILTINS AND OTHER COMMANDS | AUTHOR | COPYRIGHT

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=fish-for-bash-users&sektion=1&manpath=FreeBSD+13.0-RELEASE+and+Ports>

home | help