Difference between revisions of "Fish"

From Gentoo Wiki
Jump to:navigation Jump to:search
(→‎See also: Link to other shells.)
(revert to known-working state, before Special:diff/1061129/1072403, then re-apply subsequent changes to that. WOMM can't cut it for a shell article; there may be issues with the changed method as explained in bug 545830. changes to the way fish is set to default shell should be discussed on that bug to get input from relevant devs and contributors)
Line 13: Line 13:
 
See the [[Terminal_emulator#General_usage|terminal emulator]] article for some general usage pointers.
 
See the [[Terminal_emulator#General_usage|terminal emulator]] article for some general usage pointers.
  
{{Important|See [[Fish#Caveats|caveats section]] for how to use {{c|fish}} as a user's default shell.}}
+
{{Important|{{c|fish}} is not a POSIX compatible shell, it will cause issues if set as a user's login shell. See [[Fish#Caveats|caveats section]] for how to use {{c|fish}} as a user's default shell.}}
 
 
{{Warning|{{c|fish}} is not suitable for linking to {{c|/bin/sh}}, See the {{c|[[eselect]] sh}} utility for managing POSIX shells }}
 
  
 +
{{Warning|{{c|fish}} should not be set as the system shell by linking in /bin/sh. The {{c|[[eselect]] sh}} utility should not include a {{c|fish}} option.}}
  
 
== Installation ==
 
== Installation ==
Line 26: Line 25:
 
{{Emerge|app-shells/fish}}
 
{{Emerge|app-shells/fish}}
  
== Configuration ==
+
== Caveats ==
 
 
The command {{c|fish_config}} can manage settings on in the shell or a web browser. To use a web browser you also need a $BROWSER env var, an example of setting this would be {{c|set -gx BROWSER /usr/bin/librewolf}} run in the shell, added to the user or system as below, or in the usual bash format in /etc/env.d if you follow the steps in 'Fish as a default shell'
 
 
 
The main files for configuration are {{Path|/etc/fish/config.fish}}, which is called by every shell, and the user init file {{Path|~/.config/fish/config.fish}} which does not exist by default. If the user file exists the system file is still used automatically.
 
 
 
Both {{Path|config/fish}} and {{Path|/etc/fish}} can contain a {{Path|conf.d}} directory, this is handled slightly differently in that named files in the user's conf.d will prevent a file of the same name being sourced from {{Path|/etc/fish/conf.d}}.
 
 
 
=== Completions ===
 
 
 
{{c|fish}} has extensive completions support. Included in the source are many detailed contributed completions, and basic coverage for other things is provided by generation from {{c|man}} pages. For details on file organisation and precedence have a look at https://fishshell.com/docs/current/completions.html#where-to-put-completions
 
 
 
=== Environment variables ===
 
  
The [[Handbook:AMD64/Working/EnvVar|handbook]] explains how to set environment variables globally in the Gentoo system, for all users and the default POSIX shell. Anything using PAM will get the environment with pam_env but it's likely that many shells will start without that so extra configuration is needed.
+
In Gentoo, the login shell (the shell started after a user logs in, as defined in {{Path|/etc/passwd}}) sources {{Path|/etc/profile}}, which in turn sources {{Path|/etc/profile.env}}. This is needed to set up a functioning Gentoo environment, so a working POSIX shell is essential (see [[Login#Login shell in Gentoo|login shell in Gentoo]] for details).
  
Fish uses the same {{c|set}} command for all types of variables, with -gx (Global scope, eXported) being used for variables loaded from the environment, and has useful options like --prepend and --append.
+
{{c|fish}} can ''not'' read these files, as it is not POSIX compatible, thus it is ''strongly advised '''not''' to set {{c|fish}} '' as the login shell for any user.
  
{{FileBox|filename=~/.conf/fish/config.fish|title=Append a PATH variable in fish shell|lang=bash|1=
+
There is no reliable way to avoid this (see {{Bug|545830}}), however there is a '''good workaround''', as explained in the next section.
set -gxa PATH "$HOME/.local/bin:"
 
}}
 
  
{{FileBox|filename=~/.conf/fish/config.fish|title=Prepend a PATH variable in fish shell|lang=bash|1=
+
Those who nevertheless want to set {{c|fish}} as a default login shell can jump down to [[#Setting the fish shell as the login shell|setting the {{c|fish}} shell as the login shell]], though this is highly discouraged and can result in difficult issues.
set -gxp PATH "$HOME/.local/bin:"
 
}}
 
  
== Fish as a default shell ==
+
=== fish as a default shell with bash as the login shell ===
  
{{Note|See ongoing [[Talk:Fish|discussion]] about setting Fish as default shell with {{c|chsh}}.}}
+
The following workaround allows the use of {{c|fish}} by default, upon login or on starting a terminal emulator. This solution uses {{Path|~/.bashrc}} as a wrapper to have {{c|fish}} inherit the environment from the login shell, which is left as a bash.
  
In Gentoo a POSIX compatible login shell is needed to configure the environment (see [[Login#Login shell in Gentoo|login shell in Gentoo]] for details), you must only use {{c|chsh}} to change the shell for a user or do it at creation. Linking /bin/sh to Fish will break your system, see eslect sh for a list of POSIX shells that are suitable for this role.
+
Add the following to the user's {{Path|~/.bashrc}}, making sure it's placed below the test for an interactive shell, e.g. at the end of the file:
 
 
== Starting Fish directly ==
 
 
 
To get partial environment support you can directly source the /etc/profile.env file, which is capable of handling this type of file now.
 
 
 
{{FileBox|filename=/etc/fish/config.fish|lang=bash|1=
 
[...]
 
status -l ; and test -f /etc/profile.env ; and source /etc/profile.env
 
}}
 
 
 
This does not cover the scripts in /etc/profile.d, so if you need anything from there you will have to write your own version in Fish and then something like this to the system config so that root also gets the variables.
 
 
 
{{FileBox|filename=/etc/fish/config.fish|lang=bash|1=
 
[...]
 
status -l ; and for x in (find '/etc/profile.d/' -type f -name '*.fish')
 
  source $x
 
end
 
}}
 
 
 
== Starting Fish from Bash ==
 
The following workaround allows the use of {{c|fish}} on login or on starting a terminal emulator. This solution uses {{path|~/.bashrc}} as a wrapper to have {{c|fish}} inherit the environment from the login shell, which is left as a bash.
 
 
 
Add the following to the user's {{path|~/.bashrc}}, making sure it's placed below the test for an interactive shell, e.g. at the end of the file:
 
  
 
{{FileBox|filename=~/.bashrc|lang=bash|1=
 
{{FileBox|filename=~/.bashrc|lang=bash|1=
Line 92: Line 52:
 
Log into a new virtual console to test. Keeping open the current terminal may permit troubleshooting in case of issue with the new configuration.
 
Log into a new virtual console to test. Keeping open the current terminal may permit troubleshooting in case of issue with the new configuration.
  
{{Note|When set up this way, launching an interactive {{c|bash}} prompt will drop to {{c|fish}} because of the line added to {{path|~/.bashrc}}. To launch {{c|bash}}, ignore {{path|~/.bashrc}} (beware that any commands in {{path|~/.bashrc}} will not be executed):
+
{{Note|When set up this way, launching an interactive {{c|bash}} prompt will drop to {{c|fish}} because of the line added to {{Path|~/.bashrc}}. To launch {{c|bash}}, ignore {{Path|~/.bashrc}} (beware that any commands in {{Path|~/.bashrc}} will not be executed):
  
 
{{Cmd|bash --rcfile /etc/profile}}
 
{{Cmd|bash --rcfile /etc/profile}}
Line 98: Line 58:
  
 
This solution was suggested [https://github.com/fish-shell/fish-shell/issues/3665#issuecomment-268527236 by one of the {{c|fish}} developers], the [https://wiki.archlinux.org/index.php/Fish#Not_setting_fish_as_default_shell Arch wiki] and Gentoo devs [https://bugs.gentoo.org/545830].
 
This solution was suggested [https://github.com/fish-shell/fish-shell/issues/3665#issuecomment-268527236 by one of the {{c|fish}} developers], the [https://wiki.archlinux.org/index.php/Fish#Not_setting_fish_as_default_shell Arch wiki] and Gentoo devs [https://bugs.gentoo.org/545830].
 
=== Using Fish with Nix ===
 
 
The bashrc method above prevents {{c|nix-shell}} from applying its environment variable configuration. [https://nixos.org/ Nix] users can use the following variant to work around this problem by disabling fish execution within a nix-shell:
 
 
{{FileBox|filename=~/.bashrc|lang=bash|1=
 
[...]
 
# Use fish in place of bash
 
# keep this line at the bottom of ~/.bashrc
 
[ -x /bin/fish ] && [ -z "$IN_NIX_SHELL" ] && SHELL=/bin/fish exec fish
 
}}
 
 
With this configuration in place, running {{c|nix-shell}} will result in a bash shell. To start a nix-shell with fish, use {{c|nix-shell --command fish}}, which will correctly apply the Nix environment before launching fish.
 
  
 
=== fish as shell with bass to create and import environment ===
 
=== fish as shell with bass to create and import environment ===
Line 139: Line 86:
  
 
This solution was suggested [https://github.com/fish-shell/fish-shell/issues/3665#issuecomment-268527236 by one of the {{c|fish}} developers] and the [https://wiki.archlinux.org/index.php/Fish#Not_setting_fish_as_default_shell Arch wiki].
 
This solution was suggested [https://github.com/fish-shell/fish-shell/issues/3665#issuecomment-268527236 by one of the {{c|fish}} developers] and the [https://wiki.archlinux.org/index.php/Fish#Not_setting_fish_as_default_shell Arch wiki].
 +
 +
=== Setting the fish shell as the login shell ===
 +
 +
{{Warning|After setting {{c|fish}} as the login shell there probably will be entries missing in the <var>PATH</var> variable and some packages that rely on {{Path|/etc/profile.d}} will broken.}}
 +
 +
Those who really wish to make {{c|fish}} their login shell can still technically do so. This is not recommended and can result in a broken system:
 +
 +
{{Cmd|chsh -s /bin/fish}}
 +
 +
== Configuration ==
 +
 +
{{c|fish}} starts by executing commands in {{Path|~/.config/fish/config.fish}}. The file can be created if it does not exist.
 +
 +
Since the version 2.0 it is possible to configure fish from a web browser session by running:
 +
 +
{{Cmd|fish_config}}
 +
 +
=== Completions ===
 +
 +
{{c|fish}} can generate completions from man pages. To generate completions run:
 +
 +
{{Cmd|fish_update_completions}}
 +
 +
=== Environment variables ===
 +
 +
The [[Handbook:AMD64/Working/EnvVar|handbook]] explains how to set environment variables globally, for all users, and for the default shell (bash).
 +
 +
Fish shell sets environment variables in a different way:
 +
 +
{{FileBox|filename=~/.conf/fish/config.fish|title=Append the PATH variable for fish shell|lang=bash|1=
 +
set -gx PATH "$PATH:$HOME/.local/bin:"
 +
}}
 +
 +
== Tips ==
 +
 +
=== Using Fish with Nix ===
 +
 +
The bashrc method from the "fish as a default shell with bash as the login shell" section above prevents {{c|nix-shell}} from applying its environment variable configuration. [https://nixos.org/ Nix] users can use the following variant to work around this problem by disabling fish execution within a nix-shell:
 +
 +
{{FileBox|filename=~/.bashrc|lang=bash|1=
 +
[...]
 +
# Use fish in place of bash
 +
# keep this line at the bottom of ~/.bashrc
 +
[ -x /bin/fish ] && [ -z "$IN_NIX_SHELL" ] && SHELL=/bin/fish exec fish
 +
}}
 +
 +
With this configuration in place, running {{c|nix-shell}} will result in a bash shell. To start a nix-shell with fish, use {{c|nix-shell --command fish}}, which will correctly apply the Nix environment before launching fish.
 +
 +
== Troubleshooting ==
 +
 +
=== Garbled display ===
 +
 +
The output of a shell can, in some conditions, become corrupt. See the [[Terminal_emulator#Garbled_display|terminal emulator]] article for instructions to help fix this.
  
 
== See also ==
 
== See also ==

Revision as of 13:33, 2 October 2023

fish - the friendly interactive shell - is a smart and user-friendly command line shell for OS X, Linux, and the rest of the family. fish includes features like syntax highlighting, autosuggest-as-you-type, and fancy tab completions that just work, with no configuration required.

See the terminal emulator article for some general usage pointers.

Important
fish is not a POSIX compatible shell, it will cause issues if set as a user's login shell. See caveats section for how to use fish as a user's default shell.
Warning
fish should not be set as the system shell by linking in /bin/sh. The eselect sh utility should not include a fish option.

Installation

Emerge

Install app-shells/fish:

root #emerge --ask app-shells/fish

Caveats

In Gentoo, the login shell (the shell started after a user logs in, as defined in /etc/passwd) sources /etc/profile, which in turn sources /etc/profile.env. This is needed to set up a functioning Gentoo environment, so a working POSIX shell is essential (see login shell in Gentoo for details).

fish can not read these files, as it is not POSIX compatible, thus it is strongly advised not to set fish as the login shell for any user.

There is no reliable way to avoid this (see bug #545830), however there is a good workaround, as explained in the next section.

Those who nevertheless want to set fish as a default login shell can jump down to setting the fish shell as the login shell, though this is highly discouraged and can result in difficult issues.

fish as a default shell with bash as the login shell

The following workaround allows the use of fish by default, upon login or on starting a terminal emulator. This solution uses ~/.bashrc as a wrapper to have fish inherit the environment from the login shell, which is left as a bash.

Add the following to the user's ~/.bashrc, making sure it's placed below the test for an interactive shell, e.g. at the end of the file:

FILE ~/.bashrc
[...]
# Use fish in place of bash
# keep this line at the bottom of ~/.bashrc
[ -x /bin/fish ] && SHELL=/bin/fish exec fish

When bash is started as an interactive shell, this will automatically launch fish for the user, once bash has fully initialized the correct system environment. It will also set the SHELL environment variable to /bin/fish in fish.

Log into a new virtual console to test. Keeping open the current terminal may permit troubleshooting in case of issue with the new configuration.

Note
When set up this way, launching an interactive bash prompt will drop to fish because of the line added to ~/.bashrc. To launch bash, ignore ~/.bashrc (beware that any commands in ~/.bashrc will not be executed):
user $bash --rcfile /etc/profile

This solution was suggested by one of the fish developers, the Arch wiki and Gentoo devs [1].

fish as shell with bass to create and import environment

Once fish is installed, install bass, which will permit fish to source /etc/profile on startup. bass is a utility to execute commands in bash and replay the environment variable changes in fish. The bass site has instructions for different installation methods, such as with the fisher plugin manager or OMF. We will explain here how to install bass manually, as this is the most basic method, however a plugin manager is arguably preferable.

Move into or create a base directory for the bass repository, for example:

user $cd ~/.local/opt

Clone the bass repository (requires git), and move into the repository directory:

user ~/.local/opt $git clone https://github.com/edc/bass; cd bass

Install bass:

user ~/.local/opt/bass $make install

With bass, one can now have fish inherit the system-wide environment variables on startup, from bash.

Add the following line to ~/.config/fish/config.fish, above any other commands that would need the environment to be set up (config.fish may need to be created):

FILE ~/.config/fish/config.fish
bass source /etc/profile

Finally, restart fish if it is already running.

This solution was suggested by one of the fish developers and the Arch wiki.

Setting the fish shell as the login shell

Warning
After setting fish as the login shell there probably will be entries missing in the PATH variable and some packages that rely on /etc/profile.d will broken.

Those who really wish to make fish their login shell can still technically do so. This is not recommended and can result in a broken system:

user $chsh -s /bin/fish

Configuration

fish starts by executing commands in ~/.config/fish/config.fish. The file can be created if it does not exist.

Since the version 2.0 it is possible to configure fish from a web browser session by running:

user $fish_config

Completions

fish can generate completions from man pages. To generate completions run:

user $fish_update_completions

Environment variables

The handbook explains how to set environment variables globally, for all users, and for the default shell (bash).

Fish shell sets environment variables in a different way:

FILE ~/.conf/fish/config.fishAppend the PATH variable for fish shell
set -gx PATH "$PATH:$HOME/.local/bin:"

Tips

Using Fish with Nix

The bashrc method from the "fish as a default shell with bash as the login shell" section above prevents nix-shell from applying its environment variable configuration. Nix users can use the following variant to work around this problem by disabling fish execution within a nix-shell:

FILE ~/.bashrc
[...]
# Use fish in place of bash
# keep this line at the bottom of ~/.bashrc
[ -x /bin/fish ] && [ -z "$IN_NIX_SHELL" ] && SHELL=/bin/fish exec fish

With this configuration in place, running nix-shell will result in a bash shell. To start a nix-shell with fish, use nix-shell --command fish, which will correctly apply the Nix environment before launching fish.

Troubleshooting

Garbled display

The output of a shell can, in some conditions, become corrupt. See the terminal emulator article for instructions to help fix this.

See also

  • Shell — command-line interpreter that offers a text-based interface to users.
  • Bash — the default shell on Gentoo systems and a popular shell program found on many Linux systems.
  • Dash — a small, fast, and POSIX compliant shell.
  • Zsh — an interactive login shell that can also be used as a powerful scripting language interpreter.

External resources