Fish Shell 命令速查表 - Fish Shell 常用命令与配置大全
Fish 把语法高亮、自动补全、历史模糊搜索做成了默认行为,装完就能用,这是它和 Bash 最大的区别——不是功能更多,而是省掉了配 oh-my-zsh 那几步。真正需要下功夫的是语法差异:Fish 的 if/for/while/switch/function 都用 end 收尾,变量用 set 而非 export,列表与索引的写法也和 Bash 不同,数组下标从 1 开始。迁移时最容易出错的往往不是交互命令,而是把 .bashrc 里的片段直接搬过来。表里按变量作用域、流程控制、函数别名、字符串管道、配置主题、历史快捷键分组列出对应写法,遇到 Bash 习惯时先翻这张对照表,再决定是改脚本还是加一层 sh -c 兜底。
典型使用场景
面向从 bash/zsh 切到 fish 之后被语法绊住的人。fish 不是「换个提示符的 bash」:变量必须用 `set` 命令赋值而不是 `VAR=value` 写法,没有 `$(...)` 之外的 process substitution,列表默认按整体拼接而不做单词切分,`.bashrc` 直接 `source` 过来几乎必报错。本表把这几处真正会卡人的差异和三档变量作用域(local/global/universal)讲清楚,再补上历史搜索、字符串处理与 fisher 插件安装,够你在一周内完成迁移。
变量与作用域 7
set name "John"echo $nameset -x PATH /usr/local/bin $PATHset -U fish_user_paths /usr/local/bin $fish_user_pathsset -l local_var "value"set -g global_var "value"set -e name流程控制 5
if test -f file.txt\n echo "exists"\nendif test $count -gt 5\n echo "many"\nelse\n echo "few"\nendfor file in *.txt\n echo $file\nendwhile read -l line\n echo $line\nend < file.txtswitch $status\n case 0\n echo "success"\n case "*"\n echo "failed"\nend函数与别名 7
function greet\n echo "Hello $argv"\nendfuncsave greetfunctionsfunctions greetalias cls="clear"abbr -a gco "git checkout"funced greet字符串与管道 6
string length "hello"string split "," "a,b,c"string join ";" "a" "b" "c"string replace "old" "new" "hello old"string match -r "^\d+" "123abc"echo "data" | string upper配置与主题 6
fish_configfish_config theme choose Nordset -U fish_greeting ""fish_update_completionscat ~/.config/fish/config.fishfisher install jorgebucaran/autopair.fish命令历史与快捷键 5
historyhistory search "git"history delete "rm -rf"Ctrl+RAlt+← / Alt+→参数矩阵
| 参数 | 作用 | 示例 |
|---|---|---|
set -x / -g / -U / -l / -e | 依次为导出(环境)变量、全局变量、通用(跨会话持久)变量、局部变量与删除 | set -U fish_user_paths /usr/local/bin $fish_user_paths |
fish_greeting | 登录时的欢迎语,设为空字符串即可去掉启动横幅 | set -U fish_greeting "" |
abbr -a | 命令缩写,输入前缀后自动展开且不进入历史,比 alias 更适合替代命令 | abbr -a gco "git checkout" |
string | 内置字符串工具子命令,替代 bash 里的 cut/sed/tr/grep 组合 | string split "," "a,b,c" |
funcsave | 把当前交互式定义的函数持久化进配置文件,重开终端仍在 | funcsave greet |
易错点与避坑指南
现象把 .bashrc 里 export PATH=... 直接搬到 fish,执行后 PATH 没变,PATH 里出现一个字面量。
原因fish 里 export VAR=value 不是合法语法,变量必须用 set 命令赋值并带 -x。
处置改成 set -x PATH /usr/local/bin $PATH;要永久生效用 set -U fish_user_paths /usr/local/bin $fish_user_paths。
现象交互式定义的函数关掉终端就没了,下次又要重打一遍。
原因fish 不会自动把交互式函数写回配置文件。
处置定义后执行 funcsave greet 持久化;改动已保存的函数时用 funced greet 编辑。
现象启动时报 fish: Unknown command: [... 一堆语法错误。
原因把 bash 的 [ ] 条件语法直接搬过来,fish 用 test 而不是方括号,且 end 收尾结构不同。
处置改写成 if test $count -gt 5 / else / end 这类 fish 原生结构,逐块替换。
现象alias 定义后想禁用它时 alias name 报错说不存在。
原因fish 里 alias 是函数,删除要用 functions -e name,而不是 bash 的 unalias。
处置用 functions -e name 删除;对命令类替换优先改用 abbr -a,展开更干净。
现象PATH 里手动加的目录重启终端后又没了。
原因用 set -x 写入的只是本次会话的导出变量,没有落到持久化的 universal 变量。
处置用 set -U fish_user_paths /usr/local/bin $fish_user_paths 让它跨会话保留。
排障路径
1确认配置到底生效了没有
cat ~/.config/fish/config.fishfish 配置只读这一个文件(不含 .bashrc);改完执行 source ~/.config/fish/config.fish 立即重载。
2找一条以前打过的长命令
history search "git"等价于 Ctrl+R 的交互式增量搜索;history delete "rm -rf" 可清掉危险记录。
3查某个函数/别名的定义
functions && functions greetfunctions 列出全部,functions greet 打印单条定义,据此判断它是否被覆盖。
4装插件
fisher install jorgebucaran/autopair.fishfisher 是 fish 的插件管理器;装完检查 functions 确认插件函数已被加载。
提示
- Fish 的 if/for/function/switch 用 end 结尾,不需要 fi/done/esac。
- set -U 设置通用变量,持久化到配置文件,所有 Fish 会话共享。
- Fish 开箱即用自动补全,按 Tab 即可,按 Alt+→ 接受建议。
- fisher 是 Fish 的插件管理器:curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher。
- abbr 比 alias 更轻量,输入缩写后按空格会自动展开为完整命令。
- Fish 不兼容 POSIX Shell 语法,不能直接用 bash 脚本,但语法更直观。
- fish_config 用 fzf 交互改 PATH:set -U fish_user_paths $fish_user_paths ~/go/bin,永久生效且不重复写入。
- fish -c "命令" 可在脚本或测试里跑单条 Fish 命令,比开交互 shell 更快验证语法。
- 用 set -q 判断变量是否存在:set -q VAR; and echo yes,避免 $VAR 未定义时展开报错。
由 巧匠 维护
公开更新于 2026年7月21日,内容持续校对官方文档。