Difference between revisions of "Fish (简体中文)"

From ArchWiki
Jump to navigation Jump to search
(Added and translated section Color the hostname in the prompt in SSH 提示与技巧)
(Updated last translation time)
Line 5: Line 5:
 
[[ja:Fish]]
 
[[ja:Fish]]
 
[[ru:Fish]]
 
[[ru:Fish]]
{{TranslationStatus (简体中文)|Fish|2019-05-08|567009}}
+
{{TranslationStatus (简体中文)|Fish|2019-05-09|567009}}
 
[https://fishshell.com fish]是“'''''f'''riendly '''i'''nteractive '''sh'''ell''”的缩写,是一个“交互式的、对用户友好的 [[command-line shell|命令行shell]]”。
 
[https://fishshell.com fish]是“'''''f'''riendly '''i'''nteractive '''sh'''ell''”的缩写,是一个“交互式的、对用户友好的 [[command-line shell|命令行shell]]”。
  

Revision as of 13:13, 9 May 2019

翻译状态: 本文是英文页面 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标签下进行配置。

另请参阅