fish (简体中文)

From ArchWiki
Revision as of 13:13, 9 May 2019 by Liu-shuyuan (talk | contribs) (Updated last translation time)
Jump to navigation Jump to search

翻译状态: 本文是英文页面 Fish翻译,最后翻译时间:2019-05-09,点击这里可以查看翻译后英文页面的改动。

fish是“friendly interactive shell”的缩写,是一个“交互式的、对用户友好的 命令行shell”。

fish被有意设计成不完全与POSIX兼容。fish的作者们认为POSIX中存在一些缺陷和矛盾,并通过fish简化的或不同的语法解决这些问题。因此,即使简单的POSIX兼容的脚本也可能需要较多的修改,甚至完全重写,才能在fish中运行。

安装

安装fish软件包。也可以从AUR安装开发版的fish-gitAUR

安装完成后,输入fish即可进入fish shell。

要查看帮助文档,在fish中输入help。文档将会在浏览器中打开。建议用户至少读完文档中“Syntax overview”这一节内容,因为fish的语法和其他shell的不太一样。

把fish集成到系统中

需要考虑的是:是把fish设置为默认shell,也就是用户登录时直接进入的shell,还是通过当前的默认shell启动fish,并只在交互模式下使用fish。这里,我们假设当前的默认shell是Bash

  • 把fish设为默认shell:这种方式需要用户对fish的运行机制及其脚本语言有些基本的了解。用户需要把当前的初始化脚本和环境变量移动到fish的环境中。#把fish设为默认shell中有具体的步骤。
  • 只把fish用作交互式shell:这种方法“破坏性”较小。Bash会照常运行所有的初始化脚本,并在此基础上启动fish。#只把fish设为交互式shell中有具体的步骤。

把fish设为默认shell

如果你决定把fish设为默认的shell,首先你需要将你的用户的shell改为/usr/bin/fish。参照Command-line shell#Changing your default shell中的步骤。

下一步是把Bash的几个初始化脚本中现有的操作和配置写成fish的格式。这些脚本分别是/etc/profile~/.bash_profile/etc/bash.bashrc~/.bashrc

需要特别关注的是,在登录到fish中后,你需要尽快检查、调整环境变量$PATH的内容。在fish中,$PATH是一个全局环境变量,即它的作用范围包含所有函数,它在重启时会被清除,以及它对fish的所有子进程都是可见的(是一个环境变量)。向$PATH添加长期使用的路径的推荐的方法,是将他们赋给fish_user_paths这个全局变量。这个变量的内容重启时不会丢失,并会被自动添加到$PATH中。比如,

$ set -U fish_user_paths /第一个/路径 /第二个/路径 /第三个/路径

这三个路径就会一直保持在$PATH中。这种方式比较简单,因为不需要修改配置文件。

只把fish设为交互式shell

如果不将fish设为默认shell,就能照常运行Bash的初始化脚本。这能够保证用户当前的环境变量不受影响并且在fish中也能使用,因为fish是作为Bash的子进程运行的。下面是几种只把fish设为交互式shell的方法。

通过.bashrc启动fish

保持默认shell为Bash不变,然后添加一行exec fish到合适的Bash配置文件中,比如.bashrc。在这种方法中,Bash会正常执行/etc/profile/etc/profile.d中的所有配置文件。相对于之后几种方法,这种是最通用的,因为这种方法在本机计算机和SSH远程计算机上都能使用。

Tip:
  • 在这种配置下,要使用Bash而不是接着启动fish,需要使用bash --norc,以防止Bash加载~/.bashrc并执行exec fish
  • 要让类似于bash -c 'echo test'中的命令在Bash中执行而不是启动fish,你可以将exec fish换为if [ -z "$BASH_EXECUTION_STRING" ]; then exec fish; fi

使用终端模拟器的选项

另一种方法是在启动终端模拟器时通过添加命令行选项来启动fish。对于大部分的终端,这个选项是 -e。比如,要打开gnome-terminal并运行fish,可以将gnome-terminal的快捷方式改为:

gnome-terminal -e fish

对于不支持设置shell的终端模拟器,比如lilyterm-gitAUR,则需要这样:

SHELL=/usr/bin/fish lilyterm

另外,有些终端可以在设置或配置文件中将fish设为默认shell。

使用终端复用器的选项

要将fish设为tmux启动的默认shell,在~/.tmux.conf中加入这行:

set-option -g default-shell "/usr/bin/fish"

tmux启动时,就会自动进入fish。

配置

fish的配置脚本保存在~/.config/fish/config.fish。这个文件与 .bashrc相似,当每次启动时,fish会执行这个文件中的命令。需要注意的是,如果需要设置长期保留的变量,应该将这个变量设为一个全局变量,而不是将它定义在这些配置脚本中。

用户定义的函数保存在~/.config/fish/functions中,文件名为函数名.fish

网页界面

通过下面命令即可用浏览器打开fish的配置页面。

fish_config

在浏览器中可以交互式配置fish的配色、提示符、函数、变量、历史记录和快捷键。

命令补全

fish可以通过解析man的数据生成自动补全规则。这些自动补全规则保存于~/.config/fish/generated_completions/。可以运行下面的命令更新自动补齐规则。

fish_update_completions

你也可以在~/.config/fish/completions/中定义自己的自动补全规则。/usr/share/fish/completions/中有更多的例子。

对Arch Linux来说, pacman, pacman-key, makepkg, cower, pbget, pacmatic这些命令的自动补全规则已经在fish中内置了——fish在不同的发行版中内置了不同的命令补全规则。fish的内存管理足够智能,不会因为命令补全产生负面影响。

提示与技巧

命令替换

fish不包含Bash式的历史记录替换功能(如sudo !!)。fish的开发者在fish faq中建议使用交互式的方式调用历史记录:方向键可回顾整条命令,而Alt+上会回顾命令的单个参数。

不过,fish wiki中介绍了一些在fish中使用历史替换的办法。这种方法提供的历史替换并不完整,但可用的有!!(替换上一条命令)和!$(替换上一条命令的最后一个参数)。

串联命令

从3.0版本以后,fish不再提供串联命令符号&&!!。在fish中,推荐使用; and; or实现相似的效果。根据fish wiki中的步骤,可以通过设置快捷键自动将&&!!替换为; and; or

关闭问候语

默认情况下,每次启动fish,fish都会打印问候语。要关闭问候语,可以在fish中运行:

set -U fish_greeting

配置su命令默认启动fish

当你使用"su"用户切换到其他用户的时候,默认使用的shell是Bash,但是你可以在fish的配置文件中添加一个函数覆盖默认的"su"命令,使得你在使用"su"命令切换用户的时候会自动使用fish:

function su
    /bin/su --shell=/usr/bin/fish $argv
end

登录fish时自动开启X

把下面配置添加到 ~/.config/fish/config.fish,即可在你登录tty1的时候自动启动X。

# Start X at login
if status --is-login
    if test -z "$DISPLAY" -a $XDG_VTNR = 1
        exec startx -- -keeptty
    end
end

使用 liquidprompt

Liquidprompt是一个“用于Bash和Zsh的全功能的、经过仔细设计的、自适应的提示符”,但它目前没有计划兼容fish[1]这个项目提供了一种用于fish的实现。

在提示中增加git状态

当你处在一个git目录中时,如果你想在fish的提示符中显示分支和修改的相关信息,可以仿照以下的例子编写fish_prompt函数:

~/.config/fish/functions/fish_prompt.fish
function fish_prompt
  set -l last_status $status

  if not set -q __fish_git_prompt_show_informative_status
    set -g __fish_git_prompt_show_informative_status 1
  end
  if not set -q __fish_git_prompt_color_branch
    set -g __fish_git_prompt_color_branch brmagenta
  end
  if not set -q __fish_git_prompt_showupstream
    set -g __fish_git_prompt_showupstream "informative"
  end
  if not set -q __fish_git_prompt_showdirtystate
    set -g __fish_git_prompt_showdirtystate "yes"
  end
  if not set -q __fish_git_prompt_color_stagedstate
    set -g __fish_git_prompt_color_stagedstate yellow
  end
  if not set -q __fish_git_prompt_color_invalidstate
    set -g __fish_git_prompt_color_invalidstate red
  end
  if not set -q __fish_git_prompt_color_cleanstate
    set -g __fish_git_prompt_color_cleanstate brgreen
  end

  printf '%s%s %s%s%s%s ' (set_color $fish_color_host) (prompt_hostname) (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) (__fish_git_prompt)

  if not test $last_status -eq 0
    set_color $fish_color_error
  end
  echo -n '$ '
  set_color normal
end

然而,fish已经抛弃了这种方式,参见fish-shell git。作为替代,fish现在内置了Informative Git Prompt。该功能可以通过fish_config启用。

在SSH中用彩色显示主机名

如果需要在通过SSH登录到fish时用不同的颜色标记提示符中的主机名,请将以下内容添加到函数fish_prompt中,或者添加到fish的配置文件中。这里以红色为例:

~/.config/fish/functions/fish_prompt.fish
...
if set -q SSH_TTY
  set -g fish_color_host brred
end
...

ssh-agent 问题

在fish中,eval (ssh-agent)会因为变量的设置方式而报错。一个变通的方案是使用csh风格的选项-c

 $ eval (ssh-agent -c)

"command not found" 钩子

pkgfile 包含了一个 "未找到命令"("command not found") 钩子,但你输入一个当前系统不存在的命令,pkgfile会自动从官方仓库中搜索哪个安装包有这个命令。只要你安装了pkgfile,这个钩子就会自动启用。

从jobs中删除进程

当退出fish的时候,所有后台进程也会终止。为了保持一个任务即使在fish退出了之后也继续运行,需要先输入disown命令,再退出。举例来说,在后台启动firefox,然后退出fish,但firefox在后台继续运行:


 $ firefox &
 $ disown
 $ exit

你会发现虽然你退出了fish,但firefox没有退出。请参阅disown(1)了解更多细节。

设置别名

如果想要快速的设置一个持久化的别名(即使重启也不会失效),可以直接在fish下输入:

$ alias FooAliasName "foo"
$ funcsave FooAliasName

这样会把你的别名作为fish中的函数。如果你想查看或者编辑所有的函数可以使用fish_config,然后在Function标签下进行配置。

另请参阅