A faster interactive shell matters most once command history, completions, and prompt context start doing real work. To install Fish Shell on Ubuntu, choose the Ubuntu repository package for low maintenance, the Fish Shell release-4 PPA for the current 4.x branch, or an official standalone GitHub binary managed by a repeatable update helper.
Ubuntu keeps Bash as the default login shell until you change it with chsh. Fish can handle your interactive terminal while Bash scripts keep using their own shebangs, so the workflow separates installation, default-shell changes, first-use configuration, updates, and removal.
Install Fish Shell on Ubuntu
Choose a Fish Shell Installation Method on Ubuntu
Choose the method that matches how you want Fish updated. The Ubuntu package is the lowest-maintenance option, the release-4 PPA keeps Fish package-managed while tracking the newer major branch, and the standalone binary avoids APT package changes but needs the update helper.
| Method | Source | Update behavior | Best for |
|---|---|---|---|
| Ubuntu repository | Ubuntu universe package | apt upgrade | Repository package with minimal maintenance |
| Fish release-4 PPA | Fish Shell release-4 PPA | apt upgrade | Newer Fish 4.x package while staying inside APT |
| Standalone GitHub binary | Fish Shell GitHub releases | update-fish-standalone | Manual install under /opt with a stable /usr/local/bin/fish launcher |
The Ubuntu repository package comes from universe. If a minimal system cannot find the package, enable the component with the Ubuntu Universe repository workflow before retrying the install.
Update Ubuntu Before Installing Fish Shell
Refresh the package index first so Ubuntu uses current repository metadata for packages, dependencies, and PPA setup tools.
sudo apt update
Most commands require sudo privileges. If your account cannot run sudo, configure an administrative user first with the Ubuntu sudoers workflow.
Install Fish Shell from Ubuntu Repositories
Use the Ubuntu repository package when you want Fish maintained entirely through the standard Ubuntu archive. This method installs fish and fish-common from the enabled Ubuntu release.
sudo apt install fish
Check the installed version after APT finishes.
fish --version
fish, version 4.2.1
The exact version depends on your Ubuntu release. Current repository candidates are Fish 4.2.1 on Ubuntu 26.04, Fish 3.7.0 on Ubuntu 24.04, and Fish 3.3.1 on Ubuntu 22.04. Use the PPA method when you want the current Fish 4.x branch through APT.
Install Fish Shell from the Release-4 PPA
Use the release-4 PPA when you want a newer Fish 4.x package and still want APT to handle upgrades and removal. The PPA currently publishes Fish 4.x packages for Ubuntu 26.04, 24.04, and 22.04, while the Ubuntu archive package remains visible as a fallback candidate.
Install the repository helper package if your system does not already have it.
sudo apt install software-properties-common
Add the Fish Shell release-4 PPA, then refresh APT metadata.
sudo add-apt-repository -y ppa:fish-shell/release-4
sudo apt update
Confirm that the Fish candidate comes from the PPA before installing.
apt-cache policy fish
fish:
Installed: (none)
Candidate: 4.7.1-1~resolute
Version table:
4.7.1-1~resolute 500
500 https://ppa.launchpadcontent.net/fish-shell/release-4/ubuntu resolute/main amd64 Packages
4.2.1-3.2 500
500 http://archive.ubuntu.com/ubuntu resolute/universe amd64 Packages
Install Fish from the newly added PPA.
sudo apt install fish
Verify the installed shell version.
fish --version
fish, version 4.7.1
Install Standalone Fish Binary from GitHub Releases
Use the standalone method when you want Fish installed outside APT under /opt/fish-shell. The helper resolves the latest stable release from the Fish Shell GitHub repository, installs the official Linux binary for x86_64 or aarch64, updates a stable launcher at /usr/local/bin/fish, registers that launcher in /etc/shells, and creates a reusable update-fish-standalone command.
Use one Fish method at a time. On most Ubuntu PATH layouts,
/usr/local/bin/fishfrom the standalone method is found before/usr/bin/fishfrom APT. The standalone binary release assets do not include separate checksum or signature files; use the signed source tarball from the Fish release page if your environment requires source-level cryptographic verification.
Install the download and archive tools used by the helper. For more detail on the download flags used here, review the curl command examples.
sudo apt install curl tar xz-utils
Write the updater into /usr/local/bin so the repeat command is available from any terminal directory.
sudo tee /usr/local/bin/update-fish-standalone > /dev/null <<'SCRIPT_EOF'
#!/usr/bin/env bash
set -euo pipefail
REPO="fish-shell/fish-shell"
INSTALL_ROOT="/opt/fish-shell"
CURRENT_LINK="${INSTALL_ROOT}/current"
BIN_LINK="/usr/local/bin/fish"
TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT
need_cmds=(curl grep install ln mktemp readlink sed sudo tar uname xz)
for cmd in "${need_cmds[@]}"; do
if ! command -v "$cmd" >/dev/null 2>&1; then
echo "Error: $cmd is required but not installed." >&2
echo "Run: sudo apt install curl tar xz-utils" >&2
exit 1
fi
done
case "$(uname -m)" in
x86_64|amd64)
asset_arch="x86_64"
;;
aarch64|arm64)
asset_arch="aarch64"
;;
*)
echo "Unsupported CPU architecture: $(uname -m)" >&2
exit 1
;;
esac
latest_url="$(curl -fsSLI -o /dev/null -w '%{url_effective}' "https://github.com/${REPO}/releases/latest")"
latest_version="${latest_url##*/}"
latest_version="${latest_version#v}"
case "$latest_version" in
[0-9]*.[0-9]*.[0-9]*)
;;
*)
echo "Could not resolve a stable Fish release from ${latest_url}" >&2
exit 1
;;
esac
current_version="none"
if [ -x "$CURRENT_LINK/bin/fish" ]; then
current_version="$("$CURRENT_LINK/bin/fish" --version | sed -n 's/^fish, version //p')"
fi
echo "Current version: $current_version"
echo "Latest version: $latest_version"
if [ "$current_version" = "$latest_version" ] && [ -L "$BIN_LINK" ]; then
echo "Already up to date."
exit 0
fi
archive="fish-${latest_version}-linux-${asset_arch}.tar.xz"
download_url="https://github.com/${REPO}/releases/download/${latest_version}/${archive}"
staging="${TMP_DIR}/fish"
echo "Downloading: $archive"
curl -fsSL -o "${TMP_DIR}/${archive}" "$download_url"
mkdir -p "$staging"
tar -xJf "${TMP_DIR}/${archive}" -C "$staging"
if [ ! -x "${staging}/fish" ]; then
echo "Downloaded archive did not contain an executable fish binary." >&2
exit 1
fi
target="${INSTALL_ROOT}/fish-${latest_version}"
echo "Installing Fish $latest_version."
sudo install -d -m 0755 "$target/bin"
sudo install -m 0755 "${staging}/fish" "$target/bin/fish"
if [ -e "$BIN_LINK" ] && [ ! -L "$BIN_LINK" ]; then
echo "Error: $BIN_LINK exists and is not a symlink. Move it before continuing." >&2
exit 1
fi
if [ -L "$BIN_LINK" ]; then
link_target="$(readlink -f "$BIN_LINK")"
case "$link_target" in
"$INSTALL_ROOT"/*)
;;
*)
echo "Error: $BIN_LINK points outside $INSTALL_ROOT: $link_target" >&2
exit 1
;;
esac
fi
sudo ln -sfn "$target" "$CURRENT_LINK"
sudo ln -sfn "$CURRENT_LINK/bin/fish" "$BIN_LINK"
if ! grep -qxF "$BIN_LINK" /etc/shells; then
printf '%s\n' "$BIN_LINK" | sudo tee -a /etc/shells >/dev/null
fi
"$BIN_LINK" --version
"$BIN_LINK" -c 'echo "Fish standalone install is ready."'
echo "Standalone Fish is installed at $BIN_LINK."
SCRIPT_EOF
Make the helper executable, then confirm your shell can find it.
sudo chmod 0755 /usr/local/bin/update-fish-standalone
command -v update-fish-standalone
/usr/local/bin/update-fish-standalone
Since the helper lives in /usr/local/bin, run it by name when you install Fish or check for standalone updates later.
update-fish-standalone
The first run downloads the latest stable Fish binary, installs it under /opt/fish-shell, and connects the stable /usr/local/bin/fish launcher.
Current version: none Latest version: 4.7.1 Downloading: fish-4.7.1-linux-x86_64.tar.xz Installing Fish 4.7.1. fish, version 4.7.1 Fish standalone install is ready. Standalone Fish is installed at /usr/local/bin/fish.
A later run exits cleanly when the installed standalone release already matches the latest GitHub release.
update-fish-standalone
Current version: 4.7.1 Latest version: 4.7.1 Already up to date.
Confirm the active launcher path and version.
command -v fish
fish --version
/usr/local/bin/fish fish, version 4.7.1
Start Fish Shell and Set It as Default on Ubuntu
A shell is the program that reads your interactive terminal commands. Ubuntu opens Bash by default for most users, but you can start Fish manually at any time before changing your login shell.
fish
Leave the Fish session with exit when you want to return to the parent shell.
exit
Check which Fish executable your terminal finds. APT and PPA installs normally resolve to /usr/bin/fish, while the standalone method resolves to /usr/local/bin/fish.
command -v fish
/usr/bin/fish
Before Fish can become a login shell, its path must be listed in /etc/shells. Register the path only if it is missing.
FISH_PATH="$(command -v fish)"
grep -qxF "$FISH_PATH" /etc/shells || printf '%s\n' "$FISH_PATH" | sudo tee -a /etc/shells >/dev/null
Set Fish as your login shell.
chsh -s "$(command -v fish)"
Log out and back in, then verify the shell field for your account.
getent passwd "$USER" | cut -d: -f7
/usr/bin/fish
Fish is excellent for interactive use, but it is not a POSIX
shreplacement. Do not point/bin/shat Fish, and do not rewrite system scripts just because your login shell changed. Scripts that start with#!/bin/bashkeep running with Bash.
Get Started with Fish Shell on Ubuntu
Use Suggestions, Completions, and History Search
Fish highlights commands as you type, suggests commands from history, and expands many completions without extra plugin setup. Type part of a previous command, accept a visible suggestion with the right arrow key, or press Tab to browse completions for commands, options, files, Git branches, package names, and many common tools.
These features are interactive, so the fastest check is to start Fish and type a command fragment that already exists in your history, such as sudo apt or git. Fish shows suggestions in muted text and colors invalid command names differently from valid commands.
Open Fish Help and Web Configuration
Fish includes local help and a web-based configuration tool. From a Fish prompt, use the official Fish tutorial and Fish documentation when you want deeper details on syntax, functions, completions, and prompt customization.
help
fish_config
The fish_config command can help browse prompts, themes, functions, and variables from a local web interface. On a desktop session it opens in your browser; on a server, use the terminal output and documentation link it prints.
Create a Fish Configuration File
Fish reads user startup configuration from ~/.config/fish/config.fish. Create the directory and open the file when you want commands to run each time an interactive Fish session starts.
mkdir -p "$HOME/.config/fish"
nano "$HOME/.config/fish/config.fish"
A small starting file can keep simple aliases behind Fish’s interactive-session check.
if status is-interactive
alias ll='ls -lah'
end
Reload the file in the current Fish session after saving changes.
source "$HOME/.config/fish/config.fish"
Set Persistent Fish Preferences
Fish also supports universal variables and abbreviations that persist without editing config.fish. Run these examples from a Fish prompt, then adjust them for your own editor, PATH entries, and common commands.
set -Ux EDITOR nano
fish_add_path "$HOME/.local/bin"
abbr -a gs git status
abbr -a ga git add
abbr -a gc git commit
set -U fish_greeting
Abbreviations expand before execution, so gs becomes git status on the command line. If you use Git heavily, install Git first with the Git on Ubuntu guide so completions and examples match your workflow.
Move Bash Customizations Carefully
Fish does not read ~/.bashrc, and complex Bash functions usually need Fish syntax before they work. Move simple aliases gradually, convert frequently typed commands into abbreviations, and keep project scripts with their original #!/bin/bash or #!/usr/bin/env bash shebangs when they rely on Bash behavior.
Update Fish Shell on Ubuntu
Update APT or PPA Fish Packages
If you installed Fish from Ubuntu repositories or the release-4 PPA, normal APT upgrades include Fish updates. To check Fish directly, refresh APT metadata and upgrade only the Fish packages.
sudo apt update
sudo apt install --only-upgrade fish fish-common
Update Standalone Fish Binary
If you installed the standalone GitHub binary, rerun the helper. It resolves the latest stable release, replaces the current symlink only after a successful download and install, and exits without changes when the installed version already matches GitHub.
update-fish-standalone
Troubleshoot Fish Shell on Ubuntu
APT Cannot Locate the fish Package
If APT cannot find fish, the universe component may be disabled on a minimal or custom image.
E: Unable to locate package fish
Enable universe, refresh package metadata, and retry the install.
sudo apt install software-properties-common
sudo add-apt-repository -y universe
sudo apt update
sudo apt install fish
chsh Reports an Invalid Shell
The chsh command rejects shell paths that are missing from /etc/shells. This is most common after manual installs.
chsh: /usr/local/bin/fish is an invalid shell
Register the active Fish path, then rerun chsh.
FISH_PATH="$(command -v fish)"
grep -qxF "$FISH_PATH" /etc/shells || printf '%s\n' "$FISH_PATH" | sudo tee -a /etc/shells >/dev/null
chsh -s "$FISH_PATH"
Bash Commands from .bashrc Do Not Work in Fish
Fish uses its own scripting language. Simple aliases may be easy to recreate, but Bash-specific functions, arrays, parameter expansion, and prompt logic often need a Fish rewrite. Keep a terminal open with Bash while migrating important aliases so you can compare behavior before making Fish your default shell.
Standalone Installer Cannot Find curl
The helper checks its required commands before downloading Fish. Install the missing tools if it reports a dependency error.
Error: curl is required but not installed. Run: sudo apt install curl tar xz-utils
sudo apt install curl tar xz-utils
Remove Fish Shell from Ubuntu
Restore Bash Before Removing Fish
If Fish is your login shell, switch back to Bash before removing the Fish binary. Log out and back in after changing the shell.
chsh -s /bin/bash
Confirm that your account now points to Bash.
getent passwd "$USER" | cut -d: -f7
/bin/bash
Remove APT or PPA Fish Packages
Remove Fish packages installed from Ubuntu repositories or the release-4 PPA.
sudo apt remove fish fish-common
Preview dependencies that APT no longer needs, then run the cleanup only after the package list looks safe for your system.
sudo apt autoremove --dry-run
sudo apt autoremove
If you added the release-4 PPA, remove it and refresh package metadata. The Ubuntu PPA removal guide covers additional cleanup options for systems with many third-party repositories.
sudo add-apt-repository -y --remove ppa:fish-shell/release-4
sudo apt update
Verify that the APT packages are no longer installed.
dpkg -l fish fish-common 2>/dev/null | grep '^ii' || echo "fish packages are not installed"
fish packages are not installed
Remove Standalone Fish Binary
Removing standalone Fish deletes
/opt/fish-shell, removes the/usr/local/bin/fishlauncher, removes the helper script, and deletes the standalone shell entry from/etc/shells. It does not delete your user Fish configuration.
Preview the standalone paths before deleting them.
ls -ld /opt/fish-shell 2>/dev/null || true
ls -l /usr/local/bin/fish 2>/dev/null || true
ls -l /usr/local/bin/update-fish-standalone 2>/dev/null || true
Remove the standalone install and clear the shell command cache for the current terminal.
sudo rm -rf /opt/fish-shell
sudo rm -f /usr/local/bin/fish /usr/local/bin/update-fish-standalone
sudo sed -i '\#^/usr/local/bin/fish$#d' /etc/shells
hash -r
test ! -e /usr/local/bin/fish && echo "standalone Fish launcher removed"
command -v update-fish-standalone || echo "update-fish-standalone command not found"
Remove Fish User Configuration
Only remove user configuration when you want a full Fish reset. This deletes your Fish startup file, functions, completions, history, and universal variable data.
Review the user-level Fish directories first.
find "$HOME/.config" "$HOME/.local/share" "$HOME/.cache" -maxdepth 1 -type d -name fish -print 2>/dev/null
Delete the user-level Fish directories only after confirming that you no longer need them.
rm -rf "$HOME/.config/fish" "$HOME/.local/share/fish" "$HOME/.cache/fish"
Conclusion
Fish Shell is ready as an interactive shell through Ubuntu’s package manager, the Fish release-4 PPA, or a standalone GitHub binary with a repeatable updater. Start Fish manually before changing your login shell, then migrate aliases, abbreviations, and prompt changes gradually so existing Bash scripts keep their expected behavior.


Formatting tips for your comment
You can use basic HTML to format your comment. Useful tags currently allowed in published comments:
<code>command</code>command<strong>bold</strong><em>italic</em><blockquote>quote</blockquote>