Fish: Difference between revisions

From ArchWiki
(Add notes for command-not-found hook)
m (Undo revision 787762 by Rnwst (talk) The new bash blurb results in a: "bash: Desktop: command not found")
Tag: Undo
 
(16 intermediate revisions by 12 users not shown)
Line 2: Line 2:
[[Category:Command-line shells]]
[[Category:Command-line shells]]
[[de:Fish]]
[[de:Fish]]
[[fr:Fish]]
[[ja:Fish]]
[[ja:Fish]]
[[ru:Fish]]
[[ru:Fish]]
Line 27: Line 26:


* fish used as the '''default shell''': this mode requires some basic understanding of the fish functioning and its scripting language. The user's current initialization scripts and environment variables need to be migrated to the new fish environment. To configure the system in this mode, follow [[#Setting fish as default shell]].
* fish used as the '''default shell''': this mode requires some basic understanding of the fish functioning and its scripting language. The user's current initialization scripts and environment variables need to be migrated to the new fish environment. To configure the system in this mode, follow [[#Setting fish as default shell]].
* fish used as an '''interactive shell only''': this is the less disruptive mode, all the Bash initialization scripts are run as usual and fish runs on top of Bash in interactive mode connected to a terminal. To setup fish in this mode, follow [[#Setting fish as interactive shell only]].
* fish used as an '''interactive shell only''': this is the less disruptive mode, all the Bash initialization scripts are run as usual and fish runs on top of Bash in interactive mode connected to a terminal. To setup fish in this mode, follow [[#Setting fish as interactive shell only]].


Line 36: Line 34:
The next step is to port the current needed actions and configuration performed in the various Bash initialization scripts, namely {{ic|/etc/profile}}, {{ic|~/.bash_profile}}, {{ic|/etc/bash.bashrc}} and {{ic|~/.bashrc}}, into the fish framework.
The next step is to port the current needed actions and configuration performed in the various Bash initialization scripts, namely {{ic|/etc/profile}}, {{ic|~/.bash_profile}}, {{ic|/etc/bash.bashrc}} and {{ic|~/.bashrc}}, into the fish framework.


In particular, the content of the {{ic|$PATH}} environment variable, once directly logged under fish, should be checked and adjusted to one's need. In fish, {{ic|$PATH}} is defined as a ''global environment variable'': it has a ''global'' scope across all functions, it is lost upon reboot and it is an ''environment variable'' which means it is exported to child processes.
In particular, the content of the {{ic|$PATH}} environment variable, once directly logged under fish, should be checked and adjusted to one's need. In fish, {{ic|$PATH}} is defined as a ''global environment variable'': it has a ''global'' scope across all functions, it is lost upon reboot and it is an ''environment variable'' which means it is exported to child processes. The recommended way of adding additional locations to the path is by calling the [https://fishshell.com/docs/current/cmds/fish_add_path.html fish_add_path] command from {{ic|config.fish}}. For example:
The recommended way of adding additional locations to the path is by calling the [https://fishshell.com/docs/current/cmds/fish_add_path.html fish_add_path] command from {{ic|config.fish}}. For example:


  $ fish_add_path -p ''/first/path'' ''/second/path'' ''/third/one''
  $ fish_add_path -p ''/first/path'' ''/second/path'' ''/third/one''
Line 48: Line 45:


==== Modify .bashrc to drop into fish ====
==== Modify .bashrc to drop into fish ====
{{Accuracy|1=Using {{ic|exec fish}} in {{ic|.bashrc}} may not actually be a great idea, see e.g. https://bugzilla.redhat.com/show_bug.cgi?id=1910424.}}


Keep the default shell as Bash and simply add the line {{ic|exec fish}} to the appropriate [[Bash#Configuration files]], such as {{ic|.bashrc}}. This will allow Bash to properly source {{ic|/etc/profile}} and all files in {{ic|/etc/profile.d}}. Because fish replaces the Bash process, exiting fish will also exit the terminal. Compared to the following options, this is the most universal solution, since it works both on a local machine and on a SSH server.
Keep the default shell as Bash and simply add the line {{ic|exec fish}} to the appropriate [[Bash#Configuration files]], such as {{ic|.bashrc}}. This will allow Bash to properly source {{ic|/etc/profile}} and all files in {{ic|/etc/profile.d}}. Because fish replaces the Bash process, exiting fish will also exit the terminal. Compared to the following options, this is the most universal solution, since it works both on a local machine and on a SSH server.
Line 56: Line 51:
* In this setup, use {{ic|bash --norc}} to manually enter Bash without executing the commands from {{ic|~/.bashrc}} which would run {{ic|exec fish}} and drop back into fish.
* In this setup, use {{ic|bash --norc}} to manually enter Bash without executing the commands from {{ic|~/.bashrc}} which would run {{ic|exec fish}} and drop back into fish.
* To have commands such as {{ic|bash -c 'echo test'}} run the command in Bash instead of starting fish, you can write {{ic|if [ -z "$BASH_EXECUTION_STRING" ]; then exec fish; fi}} instead.
* To have commands such as {{ic|bash -c 'echo test'}} run the command in Bash instead of starting fish, you can write {{ic|if [ -z "$BASH_EXECUTION_STRING" ]; then exec fish; fi}} instead.
* Drop in to fish only if the parent process is not fish. This allows to quickly enter in to bash by invoking {{ic|bash}} command without losing {{ic|~/.bashrc}} configuration: {{bc|<nowiki>if [[ $(ps --no-header --pid=$PPID --format=cmd) != "fish" ]]
* In order to let fish know whether it is a login shell, you can detect login shell status in {{ic|~/.bashrc}} and pass on the {{ic|--login}} option to fish. The fish shell command {{ic|status}} can be used to show the status.
* Drop in to fish only if the parent process is not fish. This allows to quickly enter in to bash by invoking {{ic|bash}} command without losing {{ic|~/.bashrc}} configuration:
{{bc|<nowiki>if [[ $(ps --no-header --pid=$PPID --format=comm) != "fish" && -z ${BASH_EXECUTION_STRING} ]]
then
then
exec fish
shopt -q login_shell && LOGIN_OPTION='--login' || LOGIN_OPTION=''
fi</nowiki>}}}}
exec fish $LOGIN_OPTION
fi</nowiki>}}
}}


==== Use terminal emulator options ====
==== Use terminal emulator options ====
Line 103: Line 102:
You can also define your own completions in {{ic|~/.config/fish/completions/}}. See {{ic|/usr/share/fish/completions/}} for a few examples.
You can also define your own completions in {{ic|~/.config/fish/completions/}}. See {{ic|/usr/share/fish/completions/}} for a few examples.


Context-aware completions for Arch Linux-specific commands like ''pacman'', ''pacman-key'', ''makepkg'', ''cower'', ''pbget'', ''pacmatic'' are built into fish, since the policy of the fish development is to include all the existent completions in the upstream tarball. The memory management is clever enough to avoid any negative impact on resources.
Context-aware completions for Arch Linux-specific commands like ''pacman'', ''pacman-key'', ''makepkg'', ''pbget'', ''pacmatic'' are built into fish, since the policy of the fish development is to include all the existent completions in the upstream tarball. The memory management is clever enough to avoid any negative impact on resources.


== Tips and tricks ==
== Tips and tricks ==
Line 111: Line 110:
''fish'' does not implement Bash style history substitution (e.g. {{ic|sudo !!}}), and the developers recommend in the [https://fishshell.com/docs/current/faq.html#why-doesn-t-history-substitution-etc-work fish faq] to use the interactive history recall interface instead: the {{ic|Up}} arrow recalls whole past lines and {{ic|Alt+Up}} (or {{ic|Alt+.}}) recalls individual arguments, while {{ic|Alt+s}} prepends {{ic|sudo}} to the existing line.
''fish'' does not implement Bash style history substitution (e.g. {{ic|sudo !!}}), and the developers recommend in the [https://fishshell.com/docs/current/faq.html#why-doesn-t-history-substitution-etc-work fish faq] to use the interactive history recall interface instead: the {{ic|Up}} arrow recalls whole past lines and {{ic|Alt+Up}} (or {{ic|Alt+.}}) recalls individual arguments, while {{ic|Alt+s}} prepends {{ic|sudo}} to the existing line.


However some workarounds are described in the [https://github.com/fish-shell/fish-shell/wiki/Bash-Style-Command-Substitution-and-Chaining-(!!-!$-&&-%7C%7C) fish wiki]: while not providing complete history substitution, some functions replace {{ic|!!}} with the previous command or {{ic|!$}} with the previous last argument.
However some workarounds are described in the [https://github.com/fish-shell/fish-shell/wiki/Bash-Style-Command-Substitution-and-Chaining-(!!-!$) fish wiki]: while not providing complete history substitution, some functions replace {{ic|!!}} with the previous command or {{ic|!$}} with the previous last argument.
 
=== Command chaining ===
 
Command chaining {{ic|&&}} and {{ic|{{!}}{{!}}}} is not implemented in versions older than 3.0 and the recommended syntax to achieve similar results in ''fish'' is respectively {{ic|; and}} and {{ic|; or}}.
Some keybindings can be set for automatic substitution as described in the [https://github.com/fish-shell/fish-shell/wiki/Bash-Style-Command-Substitution-and-Chaining-(!!-!$-&&-%7C%7C)#getting--and- fish wiki].


=== Disable greeting ===
=== Disable greeting ===
Line 122: Line 116:
By default, fish prints a greeting message at startup. To disable it, run once:
By default, fish prints a greeting message at startup. To disable it, run once:


  $ set -U fish_greeting
$ set -U fish_greeting


This clears the universal {{ic|fish_greeting}} variable, shared with all fish instances and which is preserved upon restart of the shell.
This clears the universal {{ic|fish_greeting}} variable, shared with all fish instances and which is preserved upon restart of the shell.
Line 129: Line 123:


If ''su'' starts with Bash because Bash is the target user's (''root'' if no username is provided) default shell, one can define a function to redirect it to fish whatever the user's shell:
If ''su'' starts with Bash because Bash is the target user's (''root'' if no username is provided) default shell, one can define a function to redirect it to fish whatever the user's shell:
{{hc|~/.config/fish/functions/su.fish|2=
{{hc|~/.config/fish/functions/su.fish|2=
function su
function su
Line 138: Line 133:
Add the following to the bottom of your {{ic|~/.config/fish/config.fish}}.
Add the following to the bottom of your {{ic|~/.config/fish/config.fish}}.


{{bc|1=<nowiki>
{{bc|1=
# Start X at login
# Start X at login
if status is-login
if status is-login
Line 145: Line 140:
     end
     end
end
end
</nowiki>}}
}}


For those running fish in interactive mode, replace {{ic|status is-login}} with {{ic|status is-interactive}} in the above code.
For those running fish in interactive mode, replace {{ic|status is-login}} with {{ic|status is-interactive}} in the above code.
Line 152: Line 147:


If you would like fish to display the branch and dirty status when you are in a git directory, you can define the following {{ic|fish_prompt}} function:
If you would like fish to display the branch and dirty status when you are in a git directory, you can define the following {{ic|fish_prompt}} function:
{{hc|~/.config/fish/functions/fish_prompt.fish|
{{hc|~/.config/fish/functions/fish_prompt.fish|
<nowiki>function fish_prompt
function fish_prompt
   set -l last_status $status
   set -l last_status $status


Line 186: Line 182:
   set_color normal
   set_color normal
end
end
</nowiki>}}
}}


However, this is now deprecated, see [https://github.com/fish-shell/fish-shell/blob/master/share/functions/__fish_git_prompt.fish fish-shell git].
However, this is now deprecated, see [https://github.com/fish-shell/fish-shell/blob/master/share/functions/__fish_git_prompt.fish fish-shell git]. Alternatively, the [https://mariuszs.github.io/blog/2013/informative_git_prompt.html Informative Git Prompt] has now been built into fish and can be activated from fish_config if so desired.
Alternatively, the [https://mariuszs.github.io/blog/2013/informative_git_prompt.html Informative Git Prompt] has now been built into fish and can be activated from fish_config if so desired.


=== Color the hostname in the prompt in SSH ===
=== Color the hostname in the prompt in SSH ===
Line 200: Line 195:
   set -g fish_color_host brred
   set -g fish_color_host brred
end
end
...}}
...
}}


Note that the default fish prompt colors the hostname yellow when connected through SSH; additional modification to the prompt is not required for this functionality.
=== Evaluate ssh-agent ===
=== Evaluate ssh-agent ===


In fish, {{ic|eval (ssh-agent)}} generate errors due to how variables are set. To work around this, use the csh-style option {{ic|-c}}:
In fish, {{ic|eval (ssh-agent)}} generate errors due to how variables are set. To work around this, use the csh-style option {{ic|-c}}:


  $ eval (ssh-agent -c)
$ eval (ssh-agent -c)


=== The "command not found" hook ===
=== The "command not found" hook ===
Line 215: Line 212:


If the delay this behavior introduces is undesirable, this hook can be overridden by redefining {{ic|fish_command_not_found}} so that it only prints an error message:
If the delay this behavior introduces is undesirable, this hook can be overridden by redefining {{ic|fish_command_not_found}} so that it only prints an error message:
  $ function fish_command_not_found
 
        __fish_default_command_not_found_handler $argv[1]
$ function fish_command_not_found
    end
      __fish_default_command_not_found_handler $argv[1]
  end


To make this change permanent, the {{ic|funcsave}} built-in can be used:
To make this change permanent, the {{ic|funcsave}} built-in can be used:
  $ funcsave fish_command_not_found
 
$ funcsave fish_command_not_found


=== Remove a process from the list of jobs ===
=== Remove a process from the list of jobs ===
Line 226: Line 225:
''fish'' terminates any jobs put into the background when fish terminates. To keep a job running after fish terminates, first use the {{ic|disown}} builtin. For example, the following starts {{ic|firefox}} in the background and then disowns it:
''fish'' terminates any jobs put into the background when fish terminates. To keep a job running after fish terminates, first use the {{ic|disown}} builtin. For example, the following starts {{ic|firefox}} in the background and then disowns it:


  $ firefox &
$ firefox &
  $ disown
$ disown


This means firefox will not be closed when the fish process is closed. See {{man|1|disown|url=}} in ''fish'' for more details.
This means firefox will not be closed when the fish process is closed. See {{man|1|disown|url=}} in ''fish'' for more details.
Line 234: Line 233:


To quickly make a persistent alias, one can simply use the method showed in this example:
To quickly make a persistent alias, one can simply use the method showed in this example:
  $ alias lsl "ls -l"
  $ alias lsl "ls -l"
  $ funcsave lsl
  $ funcsave lsl
Since fish version 3.0, alias support --save(-s) option.
 
''alias'' supports the {{ic|-s}}/{{ic|--save}} option since fish version 3.0:
 
  $ alias -s lsl "ls -l"
  $ alias -s lsl "ls -l"


This will create the function:
This will create the function:
  function lsl
  function lsl
     ls -l $argv
     ls -l $argv
Line 247: Line 250:


For more detailed information, see [https://fishshell.com/docs/current/cmds/alias.html alias - create a function — fish-shell].
For more detailed information, see [https://fishshell.com/docs/current/cmds/alias.html alias - create a function — fish-shell].
=== Source /etc/profile on login ===
Unlike {{ic|bash}}, {{ic|fish}} does not source {{ic|/etc/profile}} on a tty login. If you need to source this file for
the environment variables appended and declared in the {{ic|/etc/profile.d}} directory, you can add the following to your config:
{{hc|~/.config/fish/config.fish|
# source /etc/profile with bash
if status is-login
    exec bash -c "test -e /etc/profile && source /etc/profile;\
    exec fish"
end
}}
This allows you to run {{ic|fish}} as your login shell, while still having all the environment variables you would typically
have in a {{ic|bash}} login session.


== See also ==
== See also ==

Latest revision as of 02:47, 17 September 2023

fish, the friendly interactive shell, is a commandline shell intended to be interactive and user-friendly.

fish is intentionally not fully POSIX compliant, it aims at addressing POSIX inconsistencies (as perceived by the creators) with a simplified or a different syntax. This means that even simple POSIX compliant scripts may require some significant adaptation or even full rewriting to run with fish.

Installation

Install the fish package. For the development version, install the fish-gitAUR package.

Once installed, simply type fish to drop into the fish shell.

Documentation can be found by typing help from fish; it will be opened in a web browser. It is recommended to read at least the "Syntax overview" section, since fish's syntax is different from many other shells.

System integration

One must decide whether fish is going to be the default user's shell, which means that the user falls directly in fish at login, or whether it is used in interactive terminal mode as a child process of the current default shell, here we will assume the latter is Bash. To elaborate on these two setups:

  • fish used as the default shell: this mode requires some basic understanding of the fish functioning and its scripting language. The user's current initialization scripts and environment variables need to be migrated to the new fish environment. To configure the system in this mode, follow #Setting fish as default shell.
  • fish used as an interactive shell only: this is the less disruptive mode, all the Bash initialization scripts are run as usual and fish runs on top of Bash in interactive mode connected to a terminal. To setup fish in this mode, follow #Setting fish as interactive shell only.

Setting fish as default shell

If you decide to set fish as the default user shell, the first step is to set the shell of this particular user to /usr/bin/fish. This can be done by following the instructions in Command-line shell#Changing your default shell.

The next step is to port the current needed actions and configuration performed in the various Bash initialization scripts, namely /etc/profile, ~/.bash_profile, /etc/bash.bashrc and ~/.bashrc, into the fish framework.

In particular, the content of the $PATH environment variable, once directly logged under fish, should be checked and adjusted to one's need. In fish, $PATH is defined as a global environment variable: it has a global scope across all functions, it is lost upon reboot and it is an environment variable which means it is exported to child processes. The recommended way of adding additional locations to the path is by calling the fish_add_path command from config.fish. For example:

$ fish_add_path -p /first/path /second/path /third/one

These three locations will be prepended to the path.

Setting fish as interactive shell only

Not setting fish as system wide or user default allows the current Bash scripts to run on startup. It ensures the current user's environment variables are unchanged and are exported to fish which then runs as a Bash child. Below are several ways of running fish in interactive mode without setting it as the default shell.

Modify .bashrc to drop into fish

Keep the default shell as Bash and simply add the line exec fish to the appropriate Bash#Configuration files, such as .bashrc. This will allow Bash to properly source /etc/profile and all files in /etc/profile.d. Because fish replaces the Bash process, exiting fish will also exit the terminal. Compared to the following options, this is the most universal solution, since it works both on a local machine and on a SSH server.

Tip:
  • In this setup, use bash --norc to manually enter Bash without executing the commands from ~/.bashrc which would run exec fish and drop back into fish.
  • To have commands such as bash -c 'echo test' run the command in Bash instead of starting fish, you can write if [ -z "$BASH_EXECUTION_STRING" ]; then exec fish; fi instead.
  • In order to let fish know whether it is a login shell, you can detect login shell status in ~/.bashrc and pass on the --login option to fish. The fish shell command status can be used to show the status.
  • Drop in to fish only if the parent process is not fish. This allows to quickly enter in to bash by invoking bash command without losing ~/.bashrc configuration:
if [[ $(ps --no-header --pid=$PPID --format=comm) != "fish" && -z ${BASH_EXECUTION_STRING} ]]
then
	shopt -q login_shell && LOGIN_OPTION='--login' || LOGIN_OPTION=''
	exec fish $LOGIN_OPTION
fi

Use terminal emulator options

Another option is to open your terminal emulator with a command line option that executes fish. For most terminals this is the -e switch, so for example, to open gnome-terminal using fish, change your shortcut to use:

gnome-terminal -e fish

With terminal emulators that do not support setting the shell, for example lilyterm-gitAUR, it would look like this:

SHELL=/usr/bin/fish lilyterm

Also, depending on the terminal, you may be able to set fish as the default shell in either the terminal configuration or the terminal profile.

Use terminal multiplexer options

To set fish as the shell started in tmux, put this into your ~/.tmux.conf:

set-option -g default-shell "/usr/bin/fish"

Whenever you run tmux, you will be dropped into fish.

Configuration

The configuration file runs at every login and is located at ~/.config/fish/config.fish. Adding commands or functions to the file will execute/define them when opening a terminal, similar to .bashrc. Note that whenever a variable needs to be preserved, it should be set as universal rather than defined in the aforementioned configuration file.

The user's functions are located in the directory ~/.config/fish/functions under the filenames function_name.fish.

Web interface

The fish terminal colors, prompt, functions, variables, history, bindings and abbreviations can be set with the interactive web interface:

fish_config

It may fail to start if IPv6 has been disabled. See [1] and IPv6#Disable IPv6.

Command completion

fish can generate autocompletions from man pages. Completions are written to ~/.local/share/fish/generated_completions/ and can be generated by calling:

fish_update_completions

You can also define your own completions in ~/.config/fish/completions/. See /usr/share/fish/completions/ for a few examples.

Context-aware completions for Arch Linux-specific commands like pacman, pacman-key, makepkg, pbget, pacmatic are built into fish, since the policy of the fish development is to include all the existent completions in the upstream tarball. The memory management is clever enough to avoid any negative impact on resources.

Tips and tricks

Command substitution

fish does not implement Bash style history substitution (e.g. sudo !!), and the developers recommend in the fish faq to use the interactive history recall interface instead: the Up arrow recalls whole past lines and Alt+Up (or Alt+.) recalls individual arguments, while Alt+s prepends sudo to the existing line.

However some workarounds are described in the fish wiki: while not providing complete history substitution, some functions replace !! with the previous command or !$ with the previous last argument.

Disable greeting

By default, fish prints a greeting message at startup. To disable it, run once:

$ set -U fish_greeting

This clears the universal fish_greeting variable, shared with all fish instances and which is preserved upon restart of the shell.

Make su launch fish

If su starts with Bash because Bash is the target user's (root if no username is provided) default shell, one can define a function to redirect it to fish whatever the user's shell:

~/.config/fish/functions/su.fish
function su
   command su --shell=/usr/bin/fish $argv
end

Start X at login

Add the following to the bottom of your ~/.config/fish/config.fish.

# Start X at login
if status is-login
    if test -z "$DISPLAY" -a "$XDG_VTNR" = 1
        exec startx -- -keeptty
    end
end

For those running fish in interactive mode, replace status is-login with status is-interactive in the above code.

Put git status in prompt

If you would like fish to display the branch and dirty status when you are in a git directory, you can define the following fish_prompt function:

~/.config/fish/functions/fish_prompt.fish
function fish_prompt
  set -l last_status $status

  if not set -q __fish_git_prompt_show_informative_status
    set -g __fish_git_prompt_show_informative_status 1
  end
  if not set -q __fish_git_prompt_color_branch
    set -g __fish_git_prompt_color_branch brmagenta
  end
  if not set -q __fish_git_prompt_showupstream
    set -g __fish_git_prompt_showupstream "informative"
  end
  if not set -q __fish_git_prompt_showdirtystate
    set -g __fish_git_prompt_showdirtystate "yes"
  end
  if not set -q __fish_git_prompt_color_stagedstate
    set -g __fish_git_prompt_color_stagedstate yellow
  end
  if not set -q __fish_git_prompt_color_invalidstate
    set -g __fish_git_prompt_color_invalidstate red
  end
  if not set -q __fish_git_prompt_color_cleanstate
    set -g __fish_git_prompt_color_cleanstate brgreen
  end

  printf '%s%s %s%s%s%s ' (set_color $fish_color_host) (prompt_hostname) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) (__fish_git_prompt)

  if not test $last_status -eq 0
    set_color $fish_color_error
  end
  echo -n '$ '
  set_color normal
end

However, this is now deprecated, see fish-shell git. Alternatively, the Informative Git Prompt has now been built into fish and can be activated from fish_config if so desired.

Color the hostname in the prompt in SSH

To color the hostname in the prompt dynamically whenever connected through SSH, add the following lines in either the fish_prompt function or the fish configuration file, here using the red color:

~/.config/fish/functions/fish_prompt.fish
...
if set -q SSH_TTY
  set -g fish_color_host brred
end
...

Note that the default fish prompt colors the hostname yellow when connected through SSH; additional modification to the prompt is not required for this functionality.

Evaluate ssh-agent

In fish, eval (ssh-agent) generate errors due to how variables are set. To work around this, use the csh-style option -c:

$ eval (ssh-agent -c)

The "command not found" hook

Fish includes a "command not found" hook that will automatically search the official repositories, when entering an unrecognized command. This hook will be run using pkgfile, falling back to pacman -F if it is not installed.

Since 3.2.2, "command not found" will not fallback to pacman -F by default due to its bad performance.

If the delay this behavior introduces is undesirable, this hook can be overridden by redefining fish_command_not_found so that it only prints an error message:

$ function fish_command_not_found
      __fish_default_command_not_found_handler $argv[1]
  end

To make this change permanent, the funcsave built-in can be used:

$ funcsave fish_command_not_found

Remove a process from the list of jobs

fish terminates any jobs put into the background when fish terminates. To keep a job running after fish terminates, first use the disown builtin. For example, the following starts firefox in the background and then disowns it:

$ firefox &
$ disown

This means firefox will not be closed when the fish process is closed. See disown(1) in fish for more details.

Set a persistent alias

To quickly make a persistent alias, one can simply use the method showed in this example:

$ alias lsl "ls -l"
$ funcsave lsl

alias supports the -s/--save option since fish version 3.0:

$ alias -s lsl "ls -l"

This will create the function:

function lsl
    ls -l $argv
end

and will set the alias as a persistent shell function. To see all functions and/or edit them, one can simply use fish_config and look into the Function tab in the web configuration page.

For more detailed information, see alias - create a function — fish-shell.

Source /etc/profile on login

Unlike bash, fish does not source /etc/profile on a tty login. If you need to source this file for the environment variables appended and declared in the /etc/profile.d directory, you can add the following to your config:

~/.config/fish/config.fish
# source /etc/profile with bash
if status is-login
    exec bash -c "test -e /etc/profile && source /etc/profile;\
    exec fish"
end

This allows you to run fish as your login shell, while still having all the environment variables you would typically have in a bash login session.

See also