Fish

特色

fish能根據用戶的輸入歷史與目前所在的目錄提供即時的自動完成。與bash的類似功能Ctrl+R歷史搜尋相比，這種不必頻繁切換模式還可以用方向鍵選擇建議項的做法使用戶能更流暢地進行輸入。
fish也擁有功能豐富的Tab補全功能。fish能夠自動補全檔案路徑、變數與不少命令的參數，且支援路徑萬用字元與C shell的花括號展開。fish某種意義上會通過分析命令的man文件生成與之相關的補全。
fish傾向於使用命令來代替語法結構。由於命令相比語法結構能更方便地在shell內查到幫助內容，fish的功能很容易在使用過程中被用戶自行發現。fish允許子程式提供對自己的說明，進一步免去了來回尋找幫助的麻煩。fish還允許用戶在擁有圖形化使用者介面的瀏覽器內檢視幫助。

語法

fish的語法類似於其他相容POSIX的shell，但由於其開發者認為POSIX shell設計得有問題，fish的語法又與POSIX shell有相當的不同。
# 下面演示将"bar"赋给变量foo的过程。# 由于等号在其他shell中会根据两端是否有空格而表现出不同的行为，# fish选择了不在赋值中使用这个令人困惑的符号。# set命令也可以用于数组，并可以轻松设置变量的作用域。> set foo bar
> echo $foo
bar
# 下面演示使用命令替换将pwd的输出赋给wd的过程。# 由于重音符（`）视觉上容易与单引号混淆且左右的符号都相同的话难以嵌套，# fish改为在命令替换中使用括号。# 但与ksh不同的是，fish仅在变量展开中使用美元符号。> set wd (pwd)> echo $wd
~
# 将一个有五个元素的数组赋给A。> set A 3 5 7 9 12
# 将A的第二个和第一个元素赋给B。# fish的数组索引从1开始。> set B $A[2 1]> echo $B5 3
# 可以用命令替换索引数组中的元素……> seq 3
1
2
3
> echo $A[(seq 3)]3 5 7
# ……也可以用其他数组来索引。# 下面将从A中删除第五个与第三个元素。> set --erase A[$B]> echo $A3 5 9
# for循环。> for i in *.jpg
      convert $i (basename $i .jpg).png
  end# 分号可以代替换行来标记语句的结束：> for i in *.jpg; convert $i (basename $i .jpg).png; end# 但由于fish也会在历史记录中分开记录每一行，使用换行一般更加方便。
# while循环。# 下面演示输出/etc/passwd中每行的第五个字段。> cat /etc/passwd | while read line
      set arr (echo $line|tr : \n)
      echo $arr[5]
  end

沒有子shell

其他shell的部分語法結構，例如管道、子程式與迴圈，是使用一種稱為子shell的方式實現的。所謂子shell即臨時執行一個用完即退出的新的子行程。在子shell中執行的修改通常不符合一般人的直覺地，不會反映到真正的shell上（即沒有函式副作用）。fish不依賴於子shell實現其語法結構，故所有內建命令在任何語境下都是會正常運作的。
# 相当多的shell会将read在单独的子shell中执行，所以如下语句在他们中无法按预期工作。# 在常见shell中，bash的管道右边无法产生副作用，故line并不会被赋值；# ksh中line会被正确赋值，但管道左边的语句无法产生副作用；# 但是fish和zsh一样，允许管道两边都能有副作用。> cat *.txt | read line
例如，下述bash指令碼會因為子shell而導致迴圈內部給found賦的值在退出迴圈後即消失
found=''
cat /etc/fstab | while read dev mnt rest; do
  if test "$mnt" = "/"; then
    found="$dev"
  fidone
而需要用另一種方式來規避這個問題：
found=''while read dev mnt rest; do
  if test "$mnt" = "/"; then
    found="$dev"
  fidone < /etc/fstab
如下的fish指令碼則無需擔心子shell會影響副作用。
set found ''
cat /etc/fstab | while read dev mnt rest
  if test "$mnt" = "/"
    set found $dev
  endend

有用的錯誤資訊

fish會在發生錯誤時清晰地指出出錯的位置並給出修正的方法。
> foo=bar
fish: Unknown command “foo=bar”. Did you mean “set VARIABLE VALUE”?
For information on setting variable values, see the help section on
the set command by typing “help set”.
# fish：未知的命令"foo=bar"。你是想输入"set 变量 值"吗？# 关于如何设置变量的值，请输入"help set"获取set命令的帮助。> echo ${foo}bar
fish: Did you mean {$VARIABLE}? The '$' character begins a variable
name. A bracket, which directly followed a '$', is not allowed as a
part of a variable name, and variable names may not be zero characters
long. To learn more about variable expansion in fish, type “help
expand-variable”.
# fish：你是想输入{$变量}吗？美元符号"$"仅用于变量名开头，而美元符号后的# 那个花括号并不能作为变量名称的一部分，且变量也不能没有名称。# 关于如何展开变量，请输入"help expand-variable"。> echo $(pwd)fish: Did you mean (COMMAND)? In fish, the '$' character is only used
for accessing variables. To learn more about command substitution infish, type “help expand-command-substitution”.
# fish: 你是想输入(命令)吗？在fish中，美元符号"$"仅用于访问变量。# 关于如何进行命令替换，请输入"help expand-command-substitution"。

通用變數

Fish有一個名為通用變數的功能。通過利用通用變數，用戶可以在多個同時執行的fish實體之間共用一個變數。即使用戶註銷或者電腦重新啟動，通用變數的值也不會遺失。
# 将emacs设置为默认文本编辑器。# "--universal"或者"-U"表示设置通用变量。> set --universal EDITOR emacs

# 如下命令会把fish的提示符中的当前目录变成蓝色。# 不止执行命令的这个fish，现在所有正在运行的fish的提示符都会发生变化。> set --universal fish_color_cwd blue