Listen to this Post

Introduction:
The command line has long been the domain of cryptic syntax and steep learning curves—until Fish (Friendly Interactive Shell) arrived. Created in 2005, Fish reimagines the terminal experience by prioritizing user experience above all else, offering real-time syntax highlighting, smart autosuggestions, and tab completions that work out of the box without any configuration. Unlike POSIX-compliant shells like Bash that require memorizing arcane syntax, Fish delivers immediate usability for beginners while providing the depth and customization that seasoned developers demand.
Learning Objectives:
- Understand Fish Shell’s core features and how they differ from traditional shells like Bash and Zsh
- Master the web-based configuration interface and plugin ecosystem for deep customization
- Learn practical Fish scripting techniques and productivity-enhancing workflows for daily development
- Getting Started with Fish: Installation and First Steps
Fish Shell is designed to be functional the moment you install it—no configuration files to edit, no aliases to set up, just pure productivity. Here’s how to get it running on your system:
Linux (Debian/Ubuntu):
sudo apt update sudo apt install fish
Linux (RHEL/CentOS/Fedora):
sudo dnf install fish
macOS (Homebrew):
brew install fish
Windows (WSL or Cygwin):
For WSL, use your Linux distribution's package manager For standalone, download from fishshell.com
Once installed, launch Fish by typing `fish` in your current shell. To make it your default shell:
Check your current shell echo $SHELL Set Fish as default (Linux/macOS) chsh -s /usr/bin/fish
What makes Fish immediately different: As you type, Fish color-codes your commands—valid commands appear in one color, invalid ones in another. It suggests completions from your command history in gray text; simply press the right arrow key (→) to accept the suggestion. Tab completion works universally—press Tab once for a single suggestion, twice for a full list of options. No configuration required.
2. Web-Based Configuration with fish_config
Fish offers one of the most accessible configuration systems in any shell: a browser-based interface that requires zero terminal wizardry. The `fish_config` command starts a local web server and opens a browser window where you can visually customize your environment.
Step-by-Step Guide to Using fish_config:
1. Launch the configuration interface:
fish_config
This starts a local web server and automatically opens your browser to `http://localhost:8000`.
2. Navigate the tabs:
- Choose from dozens of pre-built prompt styles or create your own
- Colors: Customize syntax highlighting colors for commands, parameters, paths, and errors
- Variables: View and edit all environment and user-defined variables
- Functions: Browse all functions defined in your Fish session
- Save your changes: Any modifications made in the browser are immediately applied to your current Fish session. Press `Ctrl+C` in the terminal to stop the web server when finished.
4. Additional fish_config commands:
List available themes fish_config theme list Apply a theme by name fish_config theme choose "Ocean" Save current theme configuration fish_config theme save
The `fish_config` utility supports subcommands for prompt and theme management, making it easy to script configuration changes.
3. Supercharging Fish with the Fisher Plugin Manager
While Fish is powerful out of the box, its true potential emerges through plugins. Fisher is the de facto plugin manager for Fish—minimal, fast, and requiring no configuration file.
Installing Fisher:
One-line installation curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher
Essential Plugins to Install Immediately:
Install plugins from GitHub fisher install jorgebucaran/nvm.fish Node version management fisher install PatrickF1/fzf.fish Fuzzy finder integration fisher install franciscolourenco/done Notifications for long-running processes List all installed plugins fisher list Update all plugins fisher update Remove a plugin fisher remove PatrickF1/fzf.fish
Fisher stores plugin references in a `fish_plugins` file, making it easy to sync your setup across machines. The plugin manager leverages Fish’s built-in tab completion, so you can tab-complete plugin names and commands seamlessly.
4. Fuzzy Finding Everything with fzf.fish
The `fzf.fish` plugin brings the power of fuzzy finding to your Fish shell, transforming how you search command history, navigate directories, and interact with Git.
Installation and Basic Usage:
Install fzf.fish fisher install PatrickF1/fzf.fish Key bindings automatically available: Ctrl+R - Fuzzy search command history Ctrl+T - Fuzzy search files (including outside current directory) Alt+C - Fuzzy change directory
Advanced fzf.fish Configuration:
Create custom fuzzy search functions in `~/.config/fish/config.fish`:
Search and kill processes interactively
function fkill -d "Fuzzy kill processes"
ps aux | fzf --multi | awk '{print $2}' | xargs kill -9
end
Search Git branches and checkout
function fco -d "Fuzzy checkout git branches"
git branch | fzf | sed 's/^..//' | xargs git checkout
end
Search through shell history with preview
function fh -d "Fuzzy search history with preview"
history | fzf --preview 'echo {}' | pbcopy
end
The `fifc` project extends this further by bringing fzf capabilities on top of Fish’s native completion engine, allowing customizable completion rules for virtually any command.
- Productivity Workflows: Abbreviations, Functions, and the `done` Plugin
Fish replaces traditional aliases with abbreviations—a more intelligent approach that expands as you type but keeps the full command in your history.
Creating Abbreviations:
Create an abbreviation (persistent) abbr -a gs "git status" abbr -a gc "git commit -m" abbr -a gco "git checkout" abbr -a dcker "docker" List all abbreviations abbr -l Remove an abbreviation abbr -e gs
Writing Fish Functions:
Functions in Fish are first-class citizens, created with the `function` keyword:
A function to create a new directory and cd into it function mkcd -d "Create directory and change into it" mkdir -p $argv[bash] cd $argv[bash] end A function with multiple arguments and error handling function backup -d "Create a timestamped backup of a file" if test -f $argv[bash] cp $argv[bash] $argv[bash].(date +%Y%m%d_%H%M%S).bak echo "Backup created: $argv[bash].(date +%Y%m%d_%H%M%S).bak" else echo "Error: File $argv[bash] not found" end end
The `done` Plugin for Long-Running Processes:
When you’re running lengthy commands—compilations, data processing, or deployments—the `done` plugin sends desktop notifications when processes complete:
Install the done plugin fisher install franciscolourenco/done After installation, any command running longer than 5 seconds will trigger a desktop notification when it finishes For example: npm install Will notify when complete docker build -t myapp . Will notify when build finishes
This is particularly valuable when multitasking, as it frees you from constantly checking terminal windows.
6. Fish Scripting: Modern Syntax for Cleaner Code
Fish’s scripting language breaks away from Bash’s cryptic syntax, offering intuitive constructs that reduce errors and improve readability.
Key Fish Scripting Patterns:
Conditional statements - clean and readable set username (whoami) if test "$username" = "root" echo "Running as root - proceed with caution" else if test "$username" = "admin" echo "Admin privileges available" else echo "Standard user: $username" end Loops with lists set fruits apple banana orange for fruit in $fruits echo "I like $fruit" end While loops set counter 0 while test $counter -lt 5 echo "Counter: $counter" set counter (math $counter + 1) end String operations with the string command set filename "project_report_2025.txt" string split "_" $filename Returns: project report 2025.txt string match ".txt" $filename Returns: project_report_2025.txt string replace "report" "summary" $filename Returns: project_summary_2025.txt
Mathematical Operations:
Fish's math command handles complex calculations math "2 + 2" 4 math "sqrt(16)" 4.000000 math "10 / 3" 3.333333 math "2^10" 1024
Creating Persistent Functions:
To make functions permanent, save them to `~/.config/fish/functions/` in files named after the function:
Create a function file echo 'function myip -d "Show my public IP" curl -s ifconfig.me end' > ~/.config/fish/functions/myip.fish Functions in this directory are automatically loaded No need to source anything
7. Advanced Tips: Shell Integration and Troubleshooting
Setting Fish as Your Default Shell with Proper Paths:
Fish doesn’t source `/etc/profile` or `~/.profile` by default, which can cause missing PATH entries. Add this to ~/.config/fish/config.fish:
Preserve system PATH set -gx PATH /usr/local/bin $PATH set -gx PATH /usr/bin $PATH Add common directories set -gx PATH ~/.local/bin $PATH set -gx PATH ~/bin $PATH Source environment variables from profile (if needed) if test -f /etc/profile bash -c 'source /etc/profile; env' | while read -l line set -gx (string split -m1 = $line) end end
Using Fish with Other Tools:
Fish’s built-in `help` command provides instant documentation:
Get help on any topic or command help syntax Opens documentation on Fish syntax help set Opens documentation on the set command help function Opens documentation on creating functions
Fish also converts its help pages to man pages, so `man set` works for Fish builtins.
Common Troubleshooting:
Debug Fish startup issues fish --debug-level=3 Run Fish without loading config fish --1o-config Check Fish version fish --version Get help with errors Fish highlights syntax errors in red as you type Invalid commands appear in red immediately
What Undercode Say:
- Fish Shell isn’t just another terminal—it’s a paradigm shift in how we interact with the command line. The real-time feedback loop of syntax highlighting and autosuggestions dramatically reduces cognitive load, allowing developers to focus on what they’re building rather than how to type the command correctly.
-
The web-based configuration and plugin ecosystem make Fish accessible to both beginners and power users. The ability to customize everything from prompt colors to complex fuzzy-finding workflows without editing obscure config files lowers the barrier to entry while providing unlimited depth for those who need it.
Fish Shell represents a fundamental rethinking of the terminal experience. Its design philosophy—intuitive by default, powerful when needed—addresses the pain points that have frustrated command-line users for decades. The immediate feedback from syntax highlighting prevents errors before they happen, while smart autosuggestions accelerate workflows without requiring memorization of command history.
For developers coming from Bash or Zsh, the transition requires adapting to Fish’s scripting syntax, which intentionally breaks POSIX compatibility to achieve cleaner, more predictable behavior. This trade-off is worthwhile: scripts written in Fish are more readable, less error-prone, and easier to maintain than their Bash counterparts.
The plugin ecosystem, centered around Fisher, provides a curated approach to extending functionality. Plugins like `fzf.fish` and `done` demonstrate how Fish can integrate with modern development tools to create a cohesive, efficient environment. The `fish_config` web interface is particularly noteworthy—it democratizes shell customization, making it accessible to users who might otherwise never modify their shell environment.
Prediction:
- +1 Fish Shell will continue gaining market share among developers, particularly in cloud-1ative and DevOps communities, as its intuitive design reduces onboarding time for new team members and its modern syntax aligns with contemporary programming language paradigms.
-
+1 The plugin ecosystem will expand significantly, with more tools offering first-class Fish support, potentially making Fish the default shell for development containers and cloud-based development environments.
-
-1 Enterprise adoption may lag due to Fish’s non-POSIX compliance, as organizations with legacy infrastructure and standardized Bash scripts will be slow to migrate. However, this creates opportunities for Fish to position itself as the shell for new projects and greenfield development.
-
-1 The learning curve for power users migrating from Bash or Zsh, particularly around scripting differences, may slow adoption among experienced sysadmins who have invested years in mastering POSIX shell scripting.
▶️ Related Video (82% Match):
https://www.youtube.com/watch?v=6eTPEg5Kklg
🎯Let’s Practice For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
IT/Security Reporter URL:
Reported By: Https: – Hackers Feeds
Extra Hub: Undercode MoN
Basic Verification: Pass ✅


