WARNING
Some of the commands used in this tutorial may not work on your machine, especially if you're using macOS instead of Linux. Tools like free, top, or certain awk filters behave differently across systems. If you run into issues, try using macOS alternatives.
Fish (Friendly Interactive Shell) is a modern, user-friendly command-line shell that offers powerful features like syntax highlighting, autosuggestions, and easy customization. This guide will walk you through downloading Fish and creating custom functions to enhance your command-line experience.
Getting Started with Fish
Launch Fish by typing fish
in your terminal, or start a new terminal session if you've set it as your default shell.
Basic Fish Configuration
Fish stores its configuration in ~/.config/fish/
. The main configuration file is config.fish
.
# Create configuration directory if it doesn't exist
mkdir -p ~/.config/fish
# Edit main configuration file
nano ~/.config/fish/config.fish
Understanding Fish Functions
Fish functions are similar to aliases or shell functions in other shells, but more powerful. They can:
- Accept arguments
- Include complex logic
- Be saved persistently
- Have descriptions and help text
Function Storage Locations
-
User functions:
~/.config/fish/functions/
-
System-wide functions:
/usr/share/fish/functions/
- Session functions: Defined in memory for current session only
Creating Your First Fish Function
Method 1: Interactive Function Creation
# Start Fish and use the function editor
function hello
echo "Hello, $argv!"
end
# Save the function permanently
funcsave hello
Method 2: Creating Function Files
Create a file in ~/.config/fish/functions/
with the function name:
# Create the functions directory
mkdir -p ~/.config/fish/functions
# Create a function file
nano ~/.config/fish/functions/hello.fish
Add the function content:
function hello --description "Say hello to someone"
if test (count $argv) -eq 0
echo "Hello, World!"
else
echo "Hello, $argv!"
end
end
Practical Fish Function Examples
1. Enhanced Directory Navigation
# ~/.config/fish/functions/mkcd.fish
function mkcd --description "Create directory and cd into it"
mkdir -p $argv[1] && cd $argv[1]
end
2. Git Shortcuts
# ~/.config/fish/functions/gst.fish
function gst --description "Git status with short format"
git status --short --branch
end
# ~/.config/fish/functions/glog.fish
function glog --description "Pretty git log"
git log --oneline --decorate --graph --all
end
# ~/.config/fish/functions/gcm.fish
function gcm --description "Git commit with message"
if test (count $argv) -eq 0
echo "Usage: gcm 'commit message'"
return 1
end
git commit -m "$argv"
end
3. System Information Functions
# ~/.config/fish/functions/sysinfo.fish
function sysinfo --description "Display system information"
echo "System Information:"
echo "=================="
echo "Hostname: "(hostname)
echo "User: "$USER
echo "OS: "(uname -s)
echo "Kernel: "(uname -r)
echo "Uptime: "(uptime | cut -d',' -f1 | cut -d' ' -f4-)
echo "Memory: "(free -h | grep '^Mem:' | awk '{print $3"/"$2}')
echo "Disk Usage: "(df -h / | tail -1 | awk '{print $5" used"}')
end
4. Development Environment Functions
# ~/.config/fish/functions/serve.fish
function serve --description "Start a simple HTTP server"
set port 8000
if test (count $argv) -gt 0
set port $argv[1]
end
if command -v python3 >/dev/null
python3 -m http.server $port
else if command -v python >/dev/null
python -m SimpleHTTPServer $port
else
echo "Python not found"
return 1
end
end
# ~/.config/fish/functions/venv.fish
function venv --description "Python virtual environment helper"
switch $argv[1]
case create
python3 -m venv $argv[2]
case activate
source $argv[2]/bin/activate.fish
case deactivate
deactivate
case '*'
echo "Usage: venv [create|activate|deactivate] [name]"
end
end
5. File and Text Manipulation
# ~/.config/fish/functions/extract.fish
function extract --description "Extract various archive formats"
if test (count $argv) -eq 0
echo "Usage: extract <archive_file>"
return 1
end
switch $argv[1]
case '*.tar.bz2'
tar xjf $argv[1]
case '*.tar.gz'
tar xzf $argv[1]
case '*.bz2'
bunzip2 $argv[1]
case '*.rar'
unrar x $argv[1]
case '*.gz'
gunzip $argv[1]
case '*.tar'
tar xf $argv[1]
case '*.tbz2'
tar xjf $argv[1]
case '*.tgz'
tar xzf $argv[1]
case '*.zip'
unzip $argv[1]
case '*.Z'
uncompress $argv[1]
case '*.7z'
7z x $argv[1]
case '*'
echo "Don't know how to extract '$argv[1]'"
return 1
end
end
Advanced Function Features
Function Arguments and Options
function myfunction --description "Example function with options"
argparse 'h/help' 'v/verbose' 'o/output=' -- $argv
or return
if set -q _flag_help
echo "Usage: myfunction [options] <input>"
echo "Options:"
echo " -h, --help Show this help"
echo " -v, --verbose Verbose output"
echo " -o, --output Specify output file"
return
end
if set -q _flag_verbose
echo "Verbose mode enabled"
end
if set -q _flag_output
echo "Output file: $_flag_output"
end
echo "Processing: $argv"
end
Using Variables and Conditionals
function backup --description "Backup files with timestamp"
set timestamp (date +%Y%m%d_%H%M%S)
if test (count $argv) -eq 0
echo "Usage: backup <file1> [file2] ..."
return 1
end
for file in $argv
if test -f $file
cp $file "$file.backup_$timestamp"
echo "Backed up: $file -> $file.backup_$timestamp"
else
echo "File not found: $file"
end
end
end
Managing Fish Functions
Listing Functions
# List all functions
functions
# List functions matching a pattern
functions | grep git
# Show function definition
functions functionname
Editing Functions
# Edit a function interactively
funced functionname
# Save changes permanently
funcsave functionname
Removing Functions
# Remove from current session
functions -e functionname
# Remove permanently
rm ~/.config/fish/functions/functionname.fish
Fish Configuration Tips
Setting Environment Variables
# In ~/.config/fish/config.fish
set -gx EDITOR vim
set -gx PATH $HOME/bin $PATH
set -gx GOPATH $HOME/go
Creating Aliases
# In ~/.config/fish/config.fish
alias python 'python3'
alias l 'ls -a'
alias ll 'ls -la'
alias grep 'grep --color=auto'
alias .. 'cd ..'
alias ... 'cd ../..'
alisa c 'clear'
Custom Prompt
# ~/.config/fish/functions/fish_prompt.fish
function fish_prompt
set_color $fish_color_cwd
echo -n (basename (prompt_pwd))
set_color normal
echo -n ' $ '
end
Troubleshooting Common Issues
Function Not Loading
- Check function file location
- Verify syntax with
fish -n ~/.config/fish/functions/functionname.fish
- Reload Fish configuration:
source ~/.config/fish/config.fish
Best Practices
- Use descriptive function names - Make them easy to remember
-
Add descriptions - Use the
--description
flag - Handle arguments properly - Check for required arguments
- Provide help information - Include usage examples
- Test functions thoroughly - Especially error conditions
- Keep functions focused - One function, one purpose
- Use meaningful variable names - Improve readability
- Comment complex logic - Help future you understand the code
Conclusion
Fish shell offers a powerful and user-friendly environment for command-line work. With custom functions, you can automate repetitive tasks, create shortcuts for complex commands, and build a personalized toolkit that matches your workflow.
Start with simple functions and gradually build more complex ones as you become comfortable with Fish's syntax and capabilities. The investment in learning Fish and creating custom functions will pay dividends in improved productivity and a more enjoyable command-line experience.
Remember to back up your Fish configuration regularly, and consider using version control to track changes to your functions and configuration files.
Top comments (0)