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

From ArchWiki
Jump to navigation Jump to search
(Updated translation of Fish - Configuration →‎配置)
(Partially updated translation of Fish - Tips and Tricks →‎提示与技巧)
Line 100: Line 100:
 
Other alternatives to regaining the {{ic|command !!}} syntax can be found on [https://github.com/fish-shell/fish-shell/wiki/Bash-Style-History-Substitution-%28%21%21-and-%21%24%29 Fish' github wiki]. The examples here include e.g. the {{ic|bind_bang}} function which expands {{ic|!!}} to the latest command in the history (this will of course make it impossible to do to bangs in a row as they will expand). Another option is the command given on [https://github.com/fish-shell/fish-shell/issues/288#issuecomment-158704275 this github issue].
 
Other alternatives to regaining the {{ic|command !!}} syntax can be found on [https://github.com/fish-shell/fish-shell/wiki/Bash-Style-History-Substitution-%28%21%21-and-%21%24%29 Fish' github wiki]. The examples here include e.g. the {{ic|bind_bang}} function which expands {{ic|!!}} to the latest command in the history (this will of course make it impossible to do to bangs in a row as they will expand). Another option is the command given on [https://github.com/fish-shell/fish-shell/issues/288#issuecomment-158704275 this github issue].
  
==提示与技巧==
+
== 提示与技巧 ==
  
=== 不要把fish设为默认shell ===
+
=== 命令替换 ===
  
在Arch中,很多shell脚本都是为[[Bash]]而写的,并且与fish不兼容。这里不建议把fish设为默认shell,把bash设为默认shell可以使得那些为bash而写的脚本可以正常运行,确保系统环境正常初始化,环境变量正常配置。如果你把fish设为默认的shell,很可能会在启动shell时看到报错信息。
+
''fish''不包含Bash式的历史记录替换功能(如{{ic|sudo !!}})。fish的开发者在[http://fishshell.com/docs/current/faq.html#faq-history fish faq]中建议使用交互式的方式调用历史记录:{{ic|上}}方向键可回顾整条命令,而{{ic|Alt+上}}会回顾命令的单个参数。
  
下面是一些技巧,能够使得即使不把fish设为默认shell,也能够在登录的时候自动进入fish。
+
不过,[https://github.com/fish-shell/fish-shell/wiki/Bash-Style-Command-Substitution-and-Chaining-(!!-!$-&&-%7C%7C) fish wiki]中介绍了一些在fish中使用历史替换的办法。这种方法提供的历史替换并不完整,但可用的有{{ic|!!}}(替换上一条命令)和{{ic|!$}}(替换上一条命令的最后一个参数)。
 
==== 修改.bashrc来启动fish ====
 
  
把bash设为你的默认shell,只需要在你的bash配置文件[[Bash#Configuration files]](一般是{{ic|.bashrc}})的最后一行加入 {{ic|exec fish}},即可在进入bash之后自动启动fish。这种做法使得Bash可以正常的运行 {{ic|/etc/profile}} 和 {{ic|/etc/profile.d}}下的配置。因为''fish''替代了bash 进程,退出 ''fish''也会自动退出终端。和下一个方法相比,这种做法更通用,因为它能够同时在本地和SSH远程连接时运作。
+
=== 串联命令 ===
  
{{Tip|如果你想进入bash而不是fish,使用命令 {{ic|bash --norc}} }}
+
从3.0版本以后,fish不再提供串联命令符号{{ic|&&}}和{{ic|!!}}。在fish中,推荐使用{{ic|; and}}和{{ic|; or}}实现相似的效果。根据[https://github.com/fish-shell/fish-shell/wiki/Bash-Style-Command-Substitution-and-Chaining-(!!-!$-&&-%7C%7C)#getting--and- fish wiki]中的步骤,可以通过设置快捷键自动将{{ic|&&}}和{{ic|!!}}替换为{{ic|; and}}和{{ic|; or}}
  
==== 设为默认终端模拟器shell ====
+
=== 关闭问候语 ===
  
另外一种自动启动fish的方法是专门针对终端模拟器设置默认解释器。对大多数终端模拟器来说,只需要{{ic|-e}} 选项即可完成配置修改。以gnome终端模拟器为例,修改使用fish的命令如下:
+
默认情况下,每次启动fish,fish都会打印问候语。要关闭问候语,可以在fish中运行:
  
gnome-terminal -e fish
+
  set -U fish_greeting
 
 
LilyTerm等轻量级的终端模拟器,不支持通过命令设置默认的解释器,这时候可以通过环境变量的方式:
 
 
 
SHELL=/usr/bin/fish lilyterm
 
 
 
你也可以通过修改终端模拟器的配置文件来完成配置。
 
 
这样,当你打开终端模拟器的时候,就会自动的进入fish。
 
 
 
====设为默认终端服用器shell ====
 
 
 
如果要为tmux设置默认的shell,只需要把下面这句话放到 {{ic|~/.tmux.conf}}:
 
 
 
  set-option -g default-shell "/usr/bin/fish"
 
 
 
这样只要启动''tmux'',都会自动进入fish。
 
 
 
===关闭问候语===
 
 
 
默认情况下,每次启动fish,fish都会打印问候语。你可以在fish的配置文件中增加 {{ic|set fish_greeting}}以关闭它。
 
  
 
=== 配置su命令默认启动fish ===
 
=== 配置su命令默认启动fish ===
Line 163: Line 141:
 
=== 使用 liquidprompt ===
 
=== 使用 liquidprompt ===
  
[https://github.com/nojhan/liquidprompt Liquidprompt] is a popular "full-featured & carefully designed adaptive prompt for Bash & Zsh" and has no plans to make it compatible with fish [https://github.com/nojhan/liquidprompt/pull/230]. [https://github.com/wesbarnett/fish-lp This project] implements it for fish.
+
[https://github.com/nojhan/liquidprompt Liquidprompt]是一个“用于Bash和Zsh的全功能的、经过仔细设计的、自适应的提示符”,但它目前没有计划兼容fish[https://github.com/nojhan/liquidprompt/pull/230][https://github.com/wesbarnett/fish-lp 这个项目]提供了一种用于fish的实现。
  
 
=== 在提示中增加git 状态 ===
 
=== 在提示中增加git 状态 ===
  
If you would like fish to display the branch and dirty status when you are in a git directory, you can add the following to your {{ic|~/.config/fish/config.fish}}:
+
当你处在一个git目录中时,如果你想在fish的提示符中显示分支和修改的相关信息,可以仿照以下的例子编写{{ic|fish_prompt}}函数:
{{bc|<nowiki>
+
 
# fish git prompt
+
{{hc|~/.config/fish/functions/fish_prompt.fish|
set __fish_git_prompt_showdirtystate 'yes'
+
<nowiki>function fish_prompt
set __fish_git_prompt_showstashstate 'yes'
+
  set -l last_status $status
set __fish_git_prompt_showupstream 'yes'
+
 
set __fish_git_prompt_color_branch yellow
+
  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)
  
# Status Chars
+
  if not test $last_status -eq 0
set __fish_git_prompt_char_dirtystate '⚡'
+
    set_color $fish_color_error
set __fish_git_prompt_char_stagedstate '→'
+
  end
set __fish_git_prompt_char_stashstate '↩'
+
  echo -n '$ '
set __fish_git_prompt_char_upstream_ahead '↑'
+
  set_color normal
set __fish_git_prompt_char_upstream_behind '↓'
 
 
function fish_prompt
 
        set last_status $status
 
        set_color $fish_color_cwd
 
        printf '%s' (prompt_pwd)
 
        set_color normal
 
        printf '%s ' (__fish_git_prompt)
 
      set_color normal
 
 
end
 
end
 
</nowiki>}}
 
</nowiki>}}
 +
More explanations about the parameters can be found in the [https://github.com/fish-shell/fish-shell/blob/master/share/functions/__fish_git_prompt.fish fish-shell git].
 +
Alternatively, the [http://mariuszs.github.io/blog/2013/informative_git_prompt.html Informative Git Prompt] has now been built into fish and can be activated from fish_config if so desired.
  
 
===  ssh-agent 问题 ===
 
===  ssh-agent 问题 ===

Revision as of 06:08, 9 May 2019

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

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 does not implement history substitution (e.g. sudo !!), and the fish developers have said that they do not plan to. Still, this is an essential piece of many users' workflow. Reddit user, crossroads1112, created a function that regains some of the functionality of history substitution and with another syntax. The function is on github and instructions are included as comments in it. There is a forked version that is closer to the original syntax and allows for command !! if you specify the command in the helper function.

Other alternatives to regaining the command !! syntax can be found on Fish' github wiki. The examples here include e.g. the bind_bang function which expands !! to the latest command in the history (this will of course make it impossible to do to bangs in a row as they will expand). Another option is the command given on this github issue.

提示与技巧

命令替换

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

More explanations about the parameters can be found in the fish-shell git. Alternatively, the Informative Git Prompt has now been built into fish and can be activated from fish_config if so desired.

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标签下进行配置。

另请参阅