Fish Shell 介绍、配置与扩展指南
Fish Shell 介绍、配置与扩展指南
引言
作为一名开发者,每天都需要在终端中工作,那么选择一个高效、智能的 shell 环境将会极大地提升生产力。之前使用的是 zsh, zsh 这需要自己进行大量的定制化配置才能满足自动补全, 语法高亮等效果. 但是在厌倦一次又一次的配置(CTRL+C + CTRL+V)之后,我尝试了 fish, 它开箱即用的特点, 让我瞬间爱上了它.
那么开始正式介绍: fish shell(Friendly Interactive Shell)
什么是 Fish Shell?
Fish shell 是一个用户友好的命令行 shell,它的设计理念是"开箱即用"(works out of the box)。与传统的 bash 或 zsh 相比,fish 提供了许多现代化的特性,让命令行操作变得更加直观和高效。
为什么选择 Fish?
Fish shell 相比传统 shell 有以下几个突出优势:
智能自动补全:Fish 提供了基于历史记录和手册页的智能自动补全功能。当你输入命令时,它会实时显示可能的补全选项,并用灰色文字提示。你只需按下右箭头键或 Tab 键就能接受建议。
语法高亮:Fish 会实时对你输入的命令进行语法高亮。正确的命令显示为绿色,错误的命令显示为红色,这让你能立即发现拼写错误或语法问题。
Web 配置界面:Fish 提供了一个基于 Web 的配置界面,你可以通过运行 fish_config 命令来打开它。在这个界面中,你可以轻松地选择主题、配置提示符、设置颜色方案等。
更简洁的脚本语法:Fish 的脚本语法更加现代和直观。例如,它使用 and 和 or 代替了 && 和 ||,使用 end 来结束代码块而不是各种括号。
安装 Fish Shell
Fish shell 的安装非常简单,以下是不同操作系统的安装方法:
macOS
# 使用 Homebrew
brew install fish
# 将 fish 设为默认 shell
echo /usr/local/bin/fish | sudo tee -a /etc/shells
chsh -s /usr/local/bin/fish
Ubuntu/Debian
# 添加官方 PPA
sudo apt-add-repository ppa:fish-shell/release-4
sudo apt update
sudo apt install fish
# 设为默认 shell
chsh -s /usr/bin/fish
基础配置
Fish 的配置文件位于 ~/.config/fish/config.fish。与 bash 的 .bashrc 类似,这个文件会在每次启动 fish 时执行。
创建配置文件
# 创建配置目录
mkdir -p ~/.config/fish
# 创建配置文件
touch ~/.config/fish/config.fish
基础配置示例
# ~/.config/fish/config.fish
# 设置编辑器
set -gx EDITOR vim
# 设置 PATH
set -gx PATH $HOME/.local/bin $PATH
# 设置别名
alias ll "ls -lah"
alias g "git"
alias dc "docker compose"
alias k "kubectl"
# 自定义欢迎消息
function fish_greeting
echo "Welcome to Fish Shell!"
echo "Today is" (date "+%Y-%m-%d %H:%M:%S")
end
# 设置代理(如果需要)
# 但是推荐参考文章末尾的 functions, 而不在 config.fish 中定义函数了.
function proxy_on
set -gx http_proxy http://127.0.0.1:7890
set -gx https_proxy http://127.0.0.1:7890
echo "Proxy enabled"
end
function proxy_off
set -e http_proxy
set -e https_proxy
echo "Proxy disabled"
end
Fisher - Fish 的包管理器
Fisher 是 fish shell 的插件管理器,它让安装和管理 fish 插件变得极其简单。Fisher 的设计理念是极简和高效,它没有外部依赖,安装速度快,配置简单。
安装 Fisher
安装 Fisher 只需要一行命令:
curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher
Fisher 基本使用
Fisher 的使用非常直观,以下是常用命令:
# 安装插件
fisher install ilancosman/tide@v6
# 列出已安装的插件
fisher list
# 更新插件
fisher update
# 删除插件
fisher remove ilancosman/tide
# 从文件安装插件列表
fisher install < fish_plugins
管理插件列表
Fisher 会自动维护一个 ~/.config/fish/fish_plugins 文件,记录所有已安装的插件。你可以将这个文件加入版本控制,方便在不同机器上同步配置:
# 保存当前插件列表
fisher list > ~/.config/fish/fish_plugins
# 在新机器上恢复插件
fisher install < ~/.config/fish/fish_plugins
推荐的 Fish 扩展
以下是一些提升 fish shell 体验的优秀扩展:
更多的 fish 拓展: https://github.com/topics/fish
1. Z - 智能目录跳转
Z 是一个纯 fish 实现的智能目录跳转工具。它会记录你访问过的目录,让你能够快速跳转到常用目录。
# 安装
fisher install jethrokuan/z
# 使用示例
cd ~/projects/my-website # 第一次需要完整路径
z website # 之后只需输入部分名称
z proj # 模糊匹配
Z 的工作原理是通过记录你访问目录的频率和时间,使用智能算法计算出最可能的目标目录。使用一段时间后,它会变得越来越智能。
2. Tide - 现代化的 Fish 提示符
Tide 是一个功能丰富、高度可定制的 Fish 提示符主题。
# 安装
fisher install ilancosman/tide@v6
# 运行配置向导
tide configure
Tide 提供了多种提示符样式,支持显示 Git 状态、执行时间、Node.js 版本、Python 虚拟环境等信息。
3. FZF - 模糊查找集成
FZF.fish 将强大的 fzf 模糊查找工具集成到 fish 中。
# 先安装 fzf
brew install fzf # macOS
# 或
sudo apt install fzf # Ubuntu
# 安装 fish 集成
fisher install PatrickF1/fzf.fish
安装后,你可以使用以下快捷键:
Ctrl+R:搜索命令历史Ctrl+Alt+F:搜索文件Ctrl+Alt+L:搜索 Git 日志Ctrl+V:搜索环境变量
4. Autopair - 自动配对括号
Autopair 自动为你输入的括号、引号等添加配对符号。
# 安装
fisher install jorgebucaran/autopair.fish
5. Done - 长时间命令完成通知
Done 会在长时间运行的命令完成后发送桌面通知。
# 安装
fisher install franciscolourenco/done
# 默认超过 5 秒的命令会触发通知
# 可以通过设置环境变量来调整
set -U __done_min_cmd_duration 3000 # 3 秒
6. Colored Man Pages - 彩色手册页
Colored Man Pages 为 man 手册页添加语法高亮。
# 安装
fisher install decors/fish-colored-man
7. Puffer Fish - Git 文本扩展
Puffer Fish 提供了 Git 命令的文本扩展功能。
# 安装
fisher install nickeb96/puffer-fish
# 使用示例
# 输入 .. 后按空格会扩展为 ../
# 输入 !! 后按空格会扩展为上一条命令
# 输入 !$ 后按空格会扩展为上一条命令的最后一个参数
实用技巧和最佳实践
1. 函数管理(functions)
Fish 中的函数可以保存为独立文件,放在 ~/.config/fish/functions/ 目录下:
# ~/.config/fish/functions/mkcd.fish
function mkcd -d "创建目录并进入"
mkdir -p $argv[1]
cd $argv[1]
end
# 使用
mkcd new-project
2. 条件配置
根据不同环境加载不同配置:
# ~/.config/fish/config.fish
# 根据操作系统加载不同配置
switch (uname)
case Darwin
source ~/.config/fish/macos.fish
case Linux
source ~/.config/fish/linux.fish
end
# 根据主机名加载特定配置
if test (hostname) = "work-laptop"
source ~/.config/fish/work.fish
end
3. 与 tmux 集成
在 ~/.config/fish/config.fish 中将内容更改为下面这样:
# 自动启动 tmux
if status is-interactive
and not set -q TMUX
exec tmux new-session -A -s main
end
从 Bash/Zsh 迁移到 Fish
如果你正在从 bash 或 zsh 迁移,以下是一些需要注意的差异:
语法差异
变量设置:
# Bash/Zsh
export PATH=$HOME/bin:$PATH
# Fish
set -gx PATH $HOME/bin $PATH
条件判断:
# Bash/Zsh
if [ -f ~/.config ]; then
echo "File exists"
fi
# Fish
if test -f ~/.config
echo "File exists"
end
循环:
# Bash/Zsh
for i in 1 2 3; do
echo $i
done
# Fish
for i in 1 2 3
echo $i
end
命令替换:
# Bash/Zsh
echo "Today is $(date)"
# Fish
echo "Today is "(date)
迁移技巧
- 使用 bass 运行 bash 脚本:
# 安装 bass
fisher install edc/bass
# 运行 bash 脚本
bass source ~/.bashrc
- 转换环境变量:
# 创建转换函数
function import_bash_env
bash -c 'source ~/.bashrc && env' | while read line
set var (echo $line | cut -d= -f1)
set val (echo $line | cut -d= -f2-)
set -gx $var $val
end
end
个人常用 fish functions 分享
快捷的 temrinal 临时代理配置
存放位置: ~/.config/fish/functions/proxy.fish
function proxy --description 'Manage HTTP/HTTPS proxy settings'
# 默认代理配置
set -l default_proxy "http://127.0.0.1:7897"
# 解析参数
argparse 'h/help' 'u/unset' 's/show' 'p/port=' 'H/host=' 't/test' -- $argv
or return 1
# 显示帮助信息
if set -q _flag_help
echo "Usage: proxy [OPTIONS] [PROXY_URL]"
echo ""
echo "Manage HTTP/HTTPS proxy settings"
echo ""
echo "Options:"
echo " -u, --unset Unset proxy environment variables"
echo " -s, --show Show current proxy configuration"
echo " -H, --host HOST Set proxy host (default: 127.0.0.1)"
echo " -p, --port PORT Set proxy port (default: 7897)"
echo " -t, --test Test proxy connection after setup"
echo " -h, --help Show this help message"
echo ""
echo "Examples:"
echo " proxy # Set default proxy (127.0.0.1:7897)"
echo " proxy --test # Set default proxy and test connection"
echo " proxy http://proxy.example.com:8080 # Set custom proxy URL"
echo " proxy -H 192.168.1.1 -p 8080 --test # Set proxy with host/port and test"
echo " proxy --show # Show current proxy settings"
echo " proxy --unset # Remove proxy settings"
return 0
end
# 显示当前代理配置
if set -q _flag_show
echo "Current Proxy Configuration:"
if set -q http_proxy; or set -q https_proxy
echo " HTTP Proxy: "(set -q http_proxy; and echo $http_proxy; or echo "(not set)")
echo " HTTPS Proxy: "(set -q https_proxy; and echo $https_proxy; or echo "(not set)")
if set -q no_proxy
echo " No Proxy: $no_proxy"
end
else
echo " No proxy configured"
end
return 0
end
# 取消代理设置
if set -q _flag_unset
set -e http_proxy
set -e https_proxy
set -e HTTP_PROXY
set -e HTTPS_PROXY
echo "✓ Proxy settings cleared"
return 0
end
# 构建代理URL
set -l proxy_url $default_proxy
# 使用host和port参数
if set -q _flag_host; or set -q _flag_port
set -l host (set -q _flag_host; and echo $_flag_host; or echo "127.0.0.1")
set -l port (set -q _flag_port; and echo $_flag_port; or echo "7897")
# 验证端口号
if not string match -qr '^\d+$' $port; or test $port -lt 1 -o $port -gt 65535
echo "Error: Invalid port number '$port'. Must be 1-65535" >&2
return 1
end
set proxy_url "http://$host:$port"
else if test (count $argv) -ge 1
set proxy_url $argv[1]
end
# 验证代理URL格式
if not string match -qr '^https?://' $proxy_url
echo "Warning: Proxy URL should start with http:// or https://"
set proxy_url "http://$proxy_url"
end
# 提取主机和端口用于显示
set -l proxy_host ""
set -l proxy_port ""
# 使用更精确的正则表达式解析URL
if string match -qr '^https?://([^:/]+)(?::(\d+))?(?:/.*)?$' $proxy_url
set proxy_host (string replace -r '^https?://([^:/]+)(?::(\d+))?(?:/.*)?$' '$1' $proxy_url)
set proxy_port (string replace -r '^https?://([^:/]+)(?::(\d+))?(?:/.*)?$' '$2' $proxy_url)
end
# 设置环境变量(同时设置大小写版本以确保兼容性)
set -gx http_proxy $proxy_url
set -gx https_proxy $proxy_url
set -gx HTTP_PROXY $proxy_url
set -gx HTTPS_PROXY $proxy_url
# 成功提示
echo "✓ Proxy configured successfully"
echo " URL: $proxy_url"
echo " Host: $proxy_host"
if test -n "$proxy_port"
echo " Port: $proxy_port"
end
# 仅在指定 --test 参数时测试代理连接
if set -q _flag_test
if command -q curl
echo "Testing proxy connection..."
# 使用Fish内置的方式处理超时,而不是依赖timeout命令
if curl -s --max-time 5 --proxy $proxy_url http://httpbin.org/ip >/dev/null 2>&1
echo "✓ Proxy connection test successful"
else
echo "⚠ Proxy connection test failed (proxy may be down or require authentication)"
end
else
echo "⚠ curl command not found, cannot test proxy connection"
end
end
# 提示常用的no_proxy设置
if not set -q no_proxy
echo ""
echo "Tip: You may want to set no_proxy for local addresses:"
echo " set -gx no_proxy localhost,127.0.0.1,::1,.local"
end
end
快捷的 terminal 临时配置 Claude Code
存放位置: ~/.config/fish/functions/setupClaudeCode.fish
function setupClaudeCode --description 'Configure Claude Code proxy with token and API endpoint'
# 默认配置
set -l default_token "[your api token]"
set -l default_base_url "[your api endpoint]"
# 解析参数
argparse 'h/help' 'c/clear' 'token=' 'u/url=' 's/show' 't/test' -- $argv
or return 1
# 显示帮助信息
if set -q _flag_help
echo "Usage: setupClaudeCode [OPTIONS]"
echo ""
echo "Configure Claude Code proxy settings"
echo ""
echo "Options:"
echo " --token TOKEN Set API token (default: masked)"
echo " -u, --url URL Set base URL (default: $default_base_url)"
echo " -s, --show Show current configuration"
echo " -c, --clear Clear all Claude Code environment variables"
echo " -t, --test Test connection after configuration"
echo " -h, --help Show this help message"
echo ""
echo "Examples:"
echo " setupClaudeCode # Use default settings"
echo " setupClaudeCode --token your_token # Set custom token"
echo " setupClaudeCode --token token -u https://api --test # Set both and test"
echo " setupClaudeCode --show # Show current config"
echo " setupClaudeCode --clear # Clear configuration"
return 0
end
# 显示当前配置
if set -q _flag_show
echo "Current Claude Code Configuration:"
if set -q ANTHROPIC_AUTH_TOKEN
echo " ANTHROPIC_AUTH_TOKEN: "(string sub -l 8 $ANTHROPIC_AUTH_TOKEN)"..."
else
echo " ANTHROPIC_AUTH_TOKEN: (not set)"
end
echo " ANTHROPIC_BASE_URL: "(set -q ANTHROPIC_BASE_URL; and echo $ANTHROPIC_BASE_URL; or echo "(not set)")
return 0
end
# 清除配置
if set -q _flag_clear
set -e ANTHROPIC_AUTH_TOKEN
set -e ANTHROPIC_BASE_URL
echo "✓ Claude Code environment variables cleared"
return 0
end
# 设置变量值
set -l api_token $default_token
set -l base_url $default_base_url
# 使用命令行参数覆盖默认值
if set -q _flag_token
set api_token $_flag_token
else if test (count $argv) -ge 1
set api_token $argv[1]
end
if set -q _flag_url
set base_url $_flag_url
else if test (count $argv) -ge 2
set base_url $argv[2]
end
# 验证输入
if test -z "$api_token"
echo "Error: API token cannot be empty" >&2
return 1
end
if test -z "$base_url"
echo "Error: Base URL cannot be empty" >&2
return 1
end
# 验证URL格式
if not string match -q "http*" $base_url
echo "Warning: Base URL should start with http:// or https://" >&2
end
# 设置环境变量
set -gx ANTHROPIC_AUTH_TOKEN $api_token
set -gx ANTHROPIC_BASE_URL $base_url
# 成功提示
echo "✓ Claude Code proxy configured successfully"
echo " Token(ANTHROPIC_AUTH_TOKEN): "(string sub -l 8 $api_token)"..."
echo " Base URL(ANTHROPIC_BASE_URL): $base_url"
# 仅在指定 --test 参数时测试连接
if set -q _flag_test
if command -q curl
echo "Testing connection..."
if curl -s --max-time 5 "$base_url" >/dev/null 2>&1
echo "✓ Connection test successful"
else
echo "⚠ Connection test failed (this might be normal if endpoint requires authentication)"
end
else
echo "⚠ curl command not found, cannot test connection"
end
end
end
参考资源
- Fish Shell 官方文档
- Fish Shell GitHub
- Fisher GitHub
- Awesome Fish - Fish 资源合集
- Fish Shell Cookbook - Fish 脚本示例集合
祝你在 Fish Shell 的世界里游得愉快!🐟