Zsh入坑&shell自动补全功能:bash和zsh;zsh启动优化

从 Bash 进阶到 Z-shell,改进你的 shell 体验。

Z-shell(Zsh)是一种 Bourne 式的交互式 POSIX shell,以其丰富的创新功能而著称。Z-Shell 用户经常会提及它的许多便利之处,赞誉它对效率的提高和丰富的自定义支持。

如果你刚接触 Linux 或 Unix,但你的经验足以让你可以打开终端并运行一些命令的话,那么你可能使用的就是 Bash shell。Bash 可能是最具有代表意义的自由软件 shell,部分是因为它具有的先进的功能,部分是因为它是大多数流行的 Linux 和 Unix 操作系统上的默认 shell。但是,随着使用的次数越多,你可能会开始发现一些细节可能能够做的更好。开源有一个众所周知的地方,那就是选择。所以,许多人选择从 Bash “毕业”到 Z。

Zsh 介绍

Shell 只是操作系统的接口。交互式 shell 程序允许你通过称为标准输入(stdin)的某个东西键入命令,并通过标准输出(stdout)和标准错误(stderr)获取输出。有很多种 shell,如 Bash、Csh、Ksh、Tcsh、Dash 和 Zsh。每个都有其开发者所认为最适合于 Shell 的功能。而这些功能的好坏,则取决于最终用户。

Zsh 具有交互式制表符补全、自动文件搜索、支持正则表达式、用于定义命令范围的高级速记符,以及丰富的主题引擎等功能。这些功能也包含在你所熟悉的其它 Bourne 式 shell 环境中,这意味着,如果你已经了解并喜欢 Bash,那么你也会熟悉 Zsh,除此以外,它还有更多的功能。你可能会认为它是一种 Bash++。

安装 Zsh

用你的包管理器安装 Zsh。

在 Fedora、RHEL 和 CentOS 上:

  1. $ sudo dnf install zsh

在 Ubuntu 和 Debian 上:

  1. $ sudo apt install zsh

在 MacOS 上你可以使用 MacPorts 安装它:

  1. $ sudo port install zsh

或使用 Homebrew:

  1. $ brew install zsh

在 Windows 上也可以运行 Zsh,但是只能在 Linux 层或类似 Linux 的层之上运行,例如 Windows 的 Linux 子系统(WSL)或 Cygwin。这类安装超出了本文的范围,因此请参考微软的文档。

设置 Zsh

Zsh 不是终端模拟器。它是在终端仿真器中运行的 shell。因此,要启动 Zsh,必须首先启动一个终端窗口,例如 GNOME Terminal、Konsole、Terminal、iTerm2、rxvt 或你喜欢的其它终端。然后,你可以通过键入以下命令启动 Zsh:

  1. $ zsh

首次启动 Zsh 时,会要求你选择一些配置选项。这些都可以在以后更改,因此请按 1 继续。

  1. This is the Z Shell configuration function for new users, zsh-newuser-install.
  2. (q)  Quit and do nothing.
  3. (0)  Exit, creating the file ~/.zshrc
  4. (1)  Continue to the main menu.

偏好设置分为四类,因此请从顶部开始。

  1. 第一个类使你可以选择在 shell 历史记录文件中保留多少个命令。默认情况下,它设置为 1,000 行。
  2. Zsh 补全是其最令人兴奋的功能之一。为了简单起见,请考虑使用其默认选项激活它,直到你习惯了它的工作方式。按 1 使用默认选项,按 2 手动设置选项。
  3. 选择 Emacs 式键绑定或 Vi 式键绑定。Bash 使用 Emacs 式绑定,因此你可能已经习惯了。
  4. 最后,你可以了解(以及设置或取消设置)Zsh 的一些精妙的功能。例如,当你提供不带命令的非可执行路径时,可以通过让 Zsh 来改变目录而无需你使用 cd 命令。要激活这些额外选项之一,请输入选项号并输入 s 进行设置。请尝试打开所有选项以获得完整的 Zsh 体验。你可以稍后通过编辑 ~/.zshrc 取消设置它们。

要完成配置,请按 0

使用 Zsh

刚开始,Zsh 的使用感受就像使用 Bash 一样,这无疑是其众多功能之一。例如,Bash 和 Tcsh 之间就存在严重的差异,因此如果你必须在工作中或在服务器上使用 Bash,而 Zsh 就可以在家里轻松尝试和使用,这样在 Bash 和 Zsh 之间轻松切换就是一种便利。

在 Zsh 中改变目录

正是这些微小的差异使 Zsh 变得好用。首先,尝试在没有 cd 命令的情况下,将目录更改为 Documents 文件夹。简直太棒了,难以置信。如果你输入的是目录路径而没有进一步的指令,Zsh 会更改为该目录:

  1. % Documents
  2. % pwd
  3. /home/seth/Documents

而这会在 Bash 或任何其他普通 shell 中导致错误。但是 Zsh 却根本不是普通的 shell,而这仅仅才是开始。

在 Zsh 中搜索

当你想使用普通 shell 程序查找文件时,可以使用 find 或 locate 命令。最起码,你可以使用 ls -R 来递归地列出一组目录。Zsh 内置有允许它在当前目录或任何其他子目录中查找文件的功能。

例如,假设你有两个名为 foo.txt 的文件。一个位于你的当前目录中,另一个位于名为 foo 的子目录中。在 Bash Shell 中,你可以使用以下命令列出当前目录中的文件:

  1. $ ls
  2. foo.txt

你可以通过明确指明子目录的路径来列出另一个目录:

  1. $ ls foo
  2. foo.txt

要同时列出这两者,你必须使用 -R 开关,并结合使用 grep

  1. $ ls -R | grep foo.txt
  2. foo.txt
  3. foo.txt

但是在 Zsh 中,你可以使用 ** 速记符号:

  1. % ls **/foo.txt
  2. foo.txt
  3. foo.txt

你可以在任何命令中使用此语法,而不仅限于 ls。想象一下在这样的场景中提高的效率:将特定文件类型从一组目录中移动到单个位置、将文本片段串联到一个文件中,或对日志进行抽取。

使用 Zsh 的制表符补全

制表符补全是 Bash 和其他一些 Shell 中的高级用户功能,它变得司空见惯,席卷了 Unix 世界。Unix 用户不再需要在输入冗长而乏味的路径时使用通配符(例如输入 /h*/s*h/V*/SCS/sc*/comp*/t*/a*/*9/04/LS*boat*v,比输入 /home/seth/Videos/SCS/scenes/composite/takes/approved/109/04/LS_boat-port-cargo-mover.mkv 要容易得多)。相反,他们只要输入足够的唯一字符串即可按 Tab 键。例如,如果你知道在系统的根目录下只有一个以 h 开头的目录,则可以键入 /h,然后单击 Tab。快速、简单、高效。它还会确认路径存在;如果 Tab 无法完成任何操作,则说明你在错误的位置或输入了错误的路径部分。

但是,如果你有许多目录有五个或更多相同的首字母,Tab 会坚决拒绝进行补全。尽管在大多数现代终端中,它将(至少会)显示阻止其进行猜测你的意思的文件,但通常需要按两次 Tab 键才能显示它们。因此,制表符补全通常会变成来回按下键盘上字母和制表符,以至于你好像在接受钢琴独奏会的训练。

Zsh 通过循环可能的补全来解决这个小问题。如果键入 ls ~/D 并按 Tab,则 Zsh 首先使用 Documents 来完成命令;如果再次按 Tab,它将提供 Downloads,依此类推,直到找到所需的选项。

Zsh 中的通配符

在 Zsh 中,通配符的行为不同于 Bash 中用户所习惯的行为。首先,可以对其进行修改。例如,如果要列出当前目录中的所有文件夹,则可以使用修改后的通配符:

  1. % ls
  2. dir0   dir1   dir2   file0   file1
  3. % ls *(/)
  4. dir0   dir1   dir2

在此示例中,(/) 限定了通配符的结果,因此 Zsh 仅显示目录。要仅列出文件,请使用 (.)。要列出符号链接,请使用 (@)。要列出可执行文件,请使用 (*)

  1. % ls ~/bin/*(*)
  2. fop  exify  tt

Zsh 不仅仅知道文件类型。它也可以使用相同的通配符修饰符约定根据修改时间列出。例如,如果要查找在过去八个小时内修改的文件,请使用 mh 修饰符(即 “modified hours” 的缩写)和小时的负整数:

  1. % ls ~/Documents/*(mh-8)
  2. cal.org   game.org   home.org

要查找超过(例如)两天前修改过的文件,修饰符更改为 md(即 “modified day” 的缩写),并带上天数的正整数:

  1. % ls ~/Documents/*(+2)
  2. holiday.org

通配符修饰符和限定符还可以做很多事情,因此,请阅读 Zsh 手册页,以获取全部详细信息。

通配符的副作用

要像在 Bash 中使用通配符一样使用它,有时必须在 Zsh 中对通配符进行转义。例如,如果要在 Bash 中将某些文件复制到服务器上,则可以使用如下通配符:

  1. $ scp IMG_*.JPG seth@example.com:~/www/ph*/*19/09/14

这在 Bash 中有效,但是在 Zsh 中会返回错误,因为它在发出 scp 命令之前尝试在远程端扩展该变量(通配符)。为避免这种情况,必须转义远程变量(通配符):

  1. % scp IMG_*.JPG seth@example.com:~/www/ph\*/\*19/09/14

当你切换到新的 shell 时,这些小异常可能会使你感到沮丧。使用 Zsh 时会遇到的问题不多(体验过 Zsh 后切换回 Bash 的可能遇到更多),但是当它们发生时,请保持镇定且坦率。严格遵守 POSIX 的情况很少会出错,但是如果失败了,请查找问题以解决并继续。对于许多在工作中困在一个 shell 上而在家中困在另一个 shell 上的用户来说,hyperpolyglot.org 已被证明其是无价的。

在我的下一篇 Zsh 文章中,我将向你展示如何安装主题和插件以定制你的 Z-Shell 甚至 Z-ier。

 

https://opensource.com/article/19/9/adding-plugins-zsh

 

前置知识:/etc/zsh/zprofile

这是一个全局的配置文件,在用户登录的时候加载。一般是用来在登录的时候执行一些命令。

解决方案

sudo gedit ~/.zprofile

添加脚本

source ~/.zshrc

bash/zsh:Linux终端启动时可自动执行命令的一些文件

某些文件

配置终端启动时自动执行一些命令, 一般是source命令,

可以在 ~/.bashrc, ~/.bash_profile, ~/.profile, 或者 ~/.zshrc 文件添加这些命令,

然后重新启动终端。

关于~/.zshrc

当 Zsh 启动时,它会按照顺序依次读取下面的配置文件:

/etc/zsh/zshenv

该文件应该包含用来设置PATH 环境变量[broken link: invalid section]以及其他一些环境变量的命令;不应该包含那些可以产生输出结果或者假设终端已经附着到 tty 上的命令。

~/.zshenv

该文件和 /etc/zsh/zshenv 相似,但是它是针对每个用户而言的。一般来说是用来设置一些有用的环境变量。

/etc/zsh/zprofile

这是一个全局的配置文件,在用户登录的时候加载。一般是用来在登录的时候执行一些命令。请注意,在 Arch Linux 里该文件默认包含一行配置,用来加载 /etc/profile 文件,详见 #全局配置文件。

/etc/profile

在登录时,该文件应该被所有和伯克利(Bourne)终端相兼容的终端加载:它在登录的的时候会加载应用相关的配置(/etc/profile.d/*.sh)。注意在 Arch Linux 里,Zsh 会默认加载该文件。

~/.zprofile

该文件一般用来在登录的时候自动执行一些用户脚本。

/etc/zsh/zshrc

当 Zsh 被作为交互式终端的时候,会加载这样一个全局配置文件。

~/.zshrc

当 Zsh 被作为交互式终端的时候,会加载这样一个用户配置文件。

/etc/zsh/zlogin

在登录完毕后加载的一个全局配置文件。

~/.zlogin

和 /etc/zsh/zlogin 相似,但是它是针对每个用户而言的。

/etc/zsh/zlogout

在注销的时候被加载的一个全局配置文件。

~/.zlogout

和 /etc/zsh/zlogout 相似,但是它是针对每个用户而言的.


原博客地址

 https://hyperpolyglot.org/unix-shells

zsh安装和配置

Zsh是一个Linux用户很少使用的power-shell,这是由于大多数Linux产品安装,以及默认使用bash shell。几乎每一款Linux产品都包含有zsh,通常可以用apt-get、urpmi或yum进行安装。zsh是兼容bash的,但是又比bash好用,有什么理由不用zsh呢?

zsh的安装

在终端中输入下面命令进行安装

sudo apt-get install zsh

安装完毕以后,你需要将zsh替换为你的默认shell,之前默认的shell为Bourne Again Shell (bash),输入下面命令进行替换

chsh -s /bin/zsh

ok,现在关闭你的终端,重新打开你的终端就可以啦

zsh的配置

一开始安装zsh时,zsh界面个人感觉是比较丑的,还好zsh有强大的配置功能,你可以任意配置你的zsh成你想要的样子,不过这里我们为了方便配置,我们采用oh-my-zsh来进行配置,oh-my-zsh是为了简化zsh的配置而提供的一个配置模板,可以更好的管理zsh的各项配置。下面我们就来安装oh-my-zsh啦 
首先你需要安装curl或者是wget

常规安装oh-my-zsh

通过curl安装

curl -L https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh | sh

通过wget安装

wget https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O - | sh

手动安装oh-my-zsh

当然你也一颗手动安装,oh-my-zsh的源码是托管于github上的 
克隆仓库里面的代码

git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh

备份你的zsh配置

cp ~/.zshrc ~/.zshrc.orig

创建一个新的zsh配置文件

cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc

改变默认的shell

chsh -s /bin/zsh

修改配置文件~/.zshrc

在你安装好oh-my-zsh以后,你的主目录下面将会有一个.oh-my-zsh目录和.zshrc配置文件。.oh-my-zsh里面存放着zsh的各种配置模板和插件,.zshrc就是在每次打开zsh的时候都会读取的配置文件啦。

首次打开你的终端时你会看到这样的zsh界面:

Alt text

是不是和bash的感觉完全不一样了,个人感觉是更好看啦

我们现在需要修改的就是配置文件啦,打开主目录下的.zshrc 
你会看到下面的配置

Alt text

找到ZSH_THEME="robbyrussell"这一行,这一行主要是配置你的zsh的提示信息的样式的,现在我们来替换成其他的主题样式

Alt text

我们将主题替换成了ZSH_THEME="xiong-chiamiov-plus",退出终端,重新打开一个终端,你会发现变成其他样式啦

Alt text

哈哈,是不是变得更加漂亮啦?如果你想要更多的主题样式,你可以到这里去找你喜欢的主题:https://github.com/robbyrussell/oh-my-zsh/wiki/themes

那要是上面的主题你都不喜欢,没关系,自己制作一个主题,打开~/.oh-my-zsh/themes目录下面的任意一个文件作为你修改的模板,博主在这里打开的是 
xiong-chiamiov-plus.zsh-theme这个文件

Alt text

打开文件以后,你会发现,这都是些啥啊??? 
Alt text

仔细一看,其实很简单,大家可以参照这篇博文对这个配置文件进行修改《linux环境变量设置(PS1,PS2)》http://blog.csdn.net/lushujun2011/article/details/7351926

下面是博主的设置文件,下载地址:《zsh与oh-my-zsh终极配置文件》http://download.csdn.net/detail/ii1245712564/8713231

    1. # Path to your oh-my-zsh installation.
    2. export ZSH=$HOME/.oh-my-zsh
    3.  
    4. # Set name of the theme to load.
    5. # Look in ~/.oh-my-zsh/themes/
    6. # Optionally, if you set this to "random", it'll load a random theme each
    7. # time that oh-my-zsh is loaded.
    8. ZSH_THEME="xiong-chiamiov-plus"
    9.  
    10. # Uncomment the following line to use case-sensitive completion.
    11. # CASE_SENSITIVE="true"
    12.  
    13. # Uncomment the following line to disable bi-weekly auto-update checks.
    14. # DISABLE_AUTO_UPDATE="true"
    15.  
    16. # Uncomment the following line to change how often to auto-update (in days).
    17. # export UPDATE_ZSH_DAYS=13
    18.  
    19. # Uncomment the following line to disable colors in ls.
    20. # DISABLE_LS_COLORS="true"
    21.  
    22. # Uncomment the following line to disable auto-setting terminal title.
    23. # DISABLE_AUTO_TITLE="true"
    24.  
    25. # Uncomment the following line to enable command auto-correction.
    26. # ENABLE_CORRECTION="true"
    27.  
    28. # Uncomment the following line to display red dots whilst waiting for completion.
    29. # COMPLETION_WAITING_DOTS="true"
    30.  
    31. # Uncomment the following line if you want to disable marking untracked files
    32. # under VCS as dirty. This makes repository status check for large repositories
    33. # much, much faster.
    34. # DISABLE_UNTRACKED_FILES_DIRTY="true"
    35.  
    36. # Uncomment the following line if you want to change the command execution time
    37. # stamp shown in the history command output.
    38. # The optional three formats: "mm/dd/yyyy"|"dd.mm.yyyy"|"yyyy-mm-dd"
    39. # HIST_STAMPS="mm/dd/yyyy"
    40.  
    41. # Would you like to use another custom folder than $ZSH/custom?
    42. # ZSH_CUSTOM=/path/to/new-custom-folder
    43.  
    44. # Which plugins would you like to load? (plugins can be found in ~/.oh-my-zsh/plugins/*)
    45. # Custom plugins may be added to ~/.oh-my-zsh/custom/plugins/
    46. # Example format: plugins=(rails git textmate ruby lighthouse)
    47. # Add wisely, as too many plugins slow down shell startup.
    48. plugins=(git)
    49.  
    50. # User configuration
    51.  
    52. export PATH=$HOME/bin:/usr/local/bin:$PATH
    53. # export MANPATH="/usr/local/man:$MANPATH"
    54.  
    55. source $ZSH/oh-my-zsh.sh
    56.  
    57. # You may need to manually set your language environment
    58. # export LANG=en_US.UTF-8
    59.  
    60. # Preferred editor for local and remote sessions
    61. # if [[ -n $SSH_CONNECTION ]]; then
    62. # export EDITOR='vim'
    63. # else
    64. # export EDITOR='mvim'
    65. # fi
    66.  
    67. # Compilation flags
    68. # export ARCHFLAGS="-arch x86_64"
    69.  
    70. # ssh
    71. # export SSH_KEY_PATH="~/.ssh/dsa_id"
    72.  
    73. # Set personal aliases, overriding those provided by oh-my-zsh libs,
    74. # plugins, and themes. Aliases can be placed here, though oh-my-zsh
    75. # users are encouraged to define aliases within the ZSH_CUSTOM folder.
    76. # For a full list of active aliases, run `alias`.
    77. #
    78. # Example aliases
    79. # alias zshconfig="mate ~/.zshrc"
    80. # alias ohmyzsh="mate ~/.oh-my-zsh"
    81.  
    82. #color{{{
    83. autoload colors
    84. colors
    85.  
    86. for color in RED GREEN YELLOW BLUE MAGENTA CYAN WHITE; do
    87. eval _$color='%{$terminfo[bold]$fg[${(L)color}]%}'
    88. eval $color='%{$fg[${(L)color}]%}'
    89. (( count = $count + 1 ))
    90. done
    91. FINISH="%{$terminfo[sgr0]%}"
    92. #}}}
    93.  
    94. #命令提示符
    95. #RPROMPT=$(echo "$RED%D %T$FINISH")
    96. #PROMPT=$(echo "$CYAN%n@$YELLOW%M:$GREEN%/$_YELLOW>$FINISH ")
    97.  
    98. #PROMPT=$(echo "$BLUE%M$GREEN%/
    99. #$CYAN%n@$BLUE%M:$GREEN%/$_YELLOW>>>$FINISH ")
    100. #标题栏、任务栏样式{{{
    101. case $TERM in (*xterm*|*rxvt*|(dt|k|E)term)
    102. precmd () { print -Pn "\e]0;%n@%M//%/\a" }
    103. preexec () { print -Pn "\e]0;%n@%M//%/\ $1\a" }
    104. ;;
    105. esac
    106. #}}}
    107.  
    108. #编辑器
    109. export EDITOR=vim
    110. #输入法
    111. export XMODIFIERS="@im=ibus"
    112. export QT_MODULE=ibus
    113. export GTK_MODULE=ibus
    114. #关于历史纪录的配置 {{{
    115. #历史纪录条目数量
    116. export HISTSIZE=10000
    117. #注销后保存的历史纪录条目数量
    118. export SAVEHIST=10000
    119. #历史纪录文件
    120. export HISTFILE=~/.zhistory
    121. #以附加的方式写入历史纪录
    122. setopt INC_APPEND_HISTORY
    123. #如果连续输入的命令相同,历史纪录中只保留一个
    124. setopt HIST_IGNORE_DUPS
    125. #为历史纪录中的命令添加时间戳
    126. setopt EXTENDED_HISTORY
    127.  
    128. #启用 cd 命令的历史纪录,cd -[TAB]进入历史路径
    129. setopt AUTO_PUSHD
    130. #相同的历史路径只保留一个
    131. setopt PUSHD_IGNORE_DUPS
    132.  
    133. #在命令前添加空格,不将此命令添加到纪录文件中
    134. #setopt HIST_IGNORE_SPACE
    135. #}}}
    136.  
    137. #每个目录使用独立的历史纪录{{{
    138. cd() {
    139. builtin cd "$@" # do actual cd
    140. fc -W # write current history file
    141. local HISTDIR="$HOME/.zsh_history$PWD" # use nested folders for history
    142. if [ ! -d "$HISTDIR" ] ; then # create folder if needed
    143. mkdir -p "$HISTDIR"
    144. fi
    145. export HISTFILE="$HISTDIR/zhistory" # set new history file
    146. touch $HISTFILE
    147. local ohistsize=$HISTSIZE
    148. HISTSIZE=0 # Discard previous dir's history
    149. HISTSIZE=$ohistsize # Prepare for new dir's history
    150. fc -R #read from current histfile
    151. }
    152. mkdir -p $HOME/.zsh_history$PWD
    153. export HISTFILE="$HOME/.zsh_history$PWD/zhistory"
    154.  
    155. function allhistory { cat $(find $HOME/.zsh_history -name zhistory) }
    156. function convhistory {
    157. sort $1 | uniq |
    158. sed 's/^:\([ 0-9]*\):[0-9]*;\(.*\)/\1::::::\2/' |
    159. awk -F"::::::" '{ $1=strftime("%Y-%m-%d %T",$1) "|"; print }'
    160. }
    161. #使用 histall 命令查看全部历史纪录
    162. function histall { convhistory =(allhistory) |
    163. sed '/^.\{20\} *cd/i\\' }
    164. #使用 hist 查看当前目录历史纪录
    165. function hist { convhistory $HISTFILE }
    166.  
    167. #全部历史纪录 top50
    168. function top50 { allhistory | awk -F':[ 0-9]*:[0-9]*;' '{ $1="" ; print }' | sed 's/ /\n/g' | sed '/^$/d' | sort | uniq -c | sort -nr | head -n 50 }
    169.  
    170. #}}}
    171.  
    172. #杂项 {{{
    173. #允许在交互模式中使用注释 例如:
    174. #cmd #这是注释
    175. setopt INTERACTIVE_COMMENTS
    176.  
    177. #启用自动 cd,输入目录名回车进入目录
    178. #稍微有点混乱,不如 cd 补全实用
    179. setopt AUTO_CD
    180.  
    181. #扩展路径
    182. #/v/c/p/p => /var/cache/pacman/pkg
    183. setopt complete_in_word
    184.  
    185. #禁用 core dumps
    186. limit coredumpsize 0
    187.  
    188. #Emacs风格 键绑定
    189. bindkey -e
    190. #bindkey -v
    191. #设置 [DEL]键 为向后删除
    192. #bindkey "\e[3~" delete-char
    193.  
    194. #以下字符视为单词的一部分
    195. WORDCHARS='*?_-[]~=&;!#$%^(){}<>'
    196. #}}}
    197.  
    198. #自动补全功能 {{{
    199. setopt AUTO_LIST
    200. setopt AUTO_MENU
    201. #开启此选项,补全时会直接选中菜单项
    202. #setopt MENU_COMPLETE
    203.  
    204. autoload -U compinit
    205. compinit
    206.  
    207. #自动补全缓存
    208. #zstyle ':completion::complete:*' use-cache on
    209. #zstyle ':completion::complete:*' cache-path .zcache
    210. #zstyle ':completion:*:cd:*' ignore-parents parent pwd
    211.  
    212. #自动补全选项
    213. zstyle ':completion:*' verbose yes
    214. zstyle ':completion:*' menu select
    215. zstyle ':completion:*:*:default' force-list always
    216. zstyle ':completion:*' select-prompt '%SSelect: lines: %L matches: %M [%p]'
    217.  
    218. zstyle ':completion:*:match:*' original only
    219. zstyle ':completion::prefix-1:*' completer _complete
    220. zstyle ':completion:predict:*' completer _complete
    221. zstyle ':completion:incremental:*' completer _complete _correct
    222. zstyle ':completion:*' completer _complete _prefix _correct _prefix _match _approximate
    223.  
    224. #路径补全
    225. zstyle ':completion:*' expand 'yes'
    226. zstyle ':completion:*' squeeze-shlashes 'yes'
    227. zstyle ':completion::complete:*' '\\'
    228.  
    229. #彩色补全菜单
    230. eval $(dircolors -b)
    231. export ZLSCOLORS="${LS_COLORS}"
    232. zmodload zsh/complist
    233. zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
    234. zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'
    235.  
    236. #修正大小写
    237. zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}'
    238. #错误校正
    239. zstyle ':completion:*' completer _complete _match _approximate
    240. zstyle ':completion:*:match:*' original only
    241. zstyle ':completion:*:approximate:*' max-errors 1 numeric
    242.  
    243. #kill 命令补全
    244. compdef pkill=kill
    245. compdef pkill=killall
    246. zstyle ':completion:*:*:kill:*' menu yes select
    247. zstyle ':completion:*:*:*:*:processes' force-list always
    248. zstyle ':completion:*:processes' command 'ps -au$USER'
    249.  
    250. #补全类型提示分组
    251. zstyle ':completion:*:matches' group 'yes'
    252. zstyle ':completion:*' group-name ''
    253. zstyle ':completion:*:options' description 'yes'
    254. zstyle ':completion:*:options' auto-description '%d'
    255. zstyle ':completion:*:descriptions' format $'\e[01;33m -- %d --\e[0m'
    256. zstyle ':completion:*:messages' format $'\e[01;35m -- %d --\e[0m'
    257. zstyle ':completion:*:warnings' format $'\e[01;31m -- No Matches Found --\e[0m'
    258. zstyle ':completion:*:corrections' format $'\e[01;32m -- %d (errors: %e) --\e[0m'
    259.  
    260. # cd ~ 补全顺序
    261. zstyle ':completion:*:-tilde-:*' group-order 'named-directories' 'path-directories' 'users' 'expand'
    262. #}}}
    263.  
    264. ##行编辑高亮模式 {{{
    265. # Ctrl+@ 设置标记,标记和光标点之间为 region
    266. zle_highlight=(region:bg=magenta #选中区域
    267. special:bold #特殊字符
    268. isearch:underline)#搜索时使用的关键字
    269. #}}}
    270.  
    271. ##空行(光标在行首)补全 "cd " {{{
    272. user-complete(){
    273. case $BUFFER in
    274. "" ) # 空行填入 "cd "
    275. BUFFER="cd "
    276. zle end-of-line
    277. zle expand-or-complete
    278. ;;
    279. "cd --" ) # "cd --" 替换为 "cd +"
    280. BUFFER="cd +"
    281. zle end-of-line
    282. zle expand-or-complete
    283. ;;
    284. "cd +-" ) # "cd +-" 替换为 "cd -"
    285. BUFFER="cd -"
    286. zle end-of-line
    287. zle expand-or-complete
    288. ;;
    289. * )
    290. zle expand-or-complete
    291. ;;
    292. esac
    293. }
    294. zle -N user-complete
    295. bindkey "\t" user-complete
    296. #}}}
    297.  
    298. ##在命令前插入 sudo {{{
    299. #定义功能
    300. sudo-command-line() {
    301. [[ -z $BUFFER ]] && zle up-history
    302. [[ $BUFFER != sudo\ * ]] && BUFFER="sudo $BUFFER"
    303. zle end-of-line #光标移动到行末
    304. }
    305. zle -N sudo-command-line
    306. #定义快捷键为: [Esc] [Esc]
    307. bindkey "\e\e" sudo-command-line
    308. #}}}
    309.  
    310. #命令别名 {{{
    311. alias cp='cp -i'
    312. alias mv='mv -i'
    313. alias rm='rm -i'
    314. alias ls='ls -F --color=auto'
    315. alias ll='ls -al'
    316. alias grep='grep --color=auto'
    317. alias la='ls -a'
    318. alias pacman='sudo pacman-color'
    319. alias p='sudo pacman-color'
    320. alias y='yaourt'
    321. alias h='htop'
    322. alias vim='vim'
    323.  
    324. #[Esc][h] man 当前命令时,显示简短说明
    325. alias run-help >&/dev/null && unalias run-help
    326. autoload run-help
    327.  
    328. #历史命令 top10
    329. alias top10='print -l ${(o)history%% *} | uniq -c | sort -nr | head -n 10'
    330. #}}}
    331.  
    332. #路径别名 {{{
    333. #进入相应的路径时只要 cd ~xxx
    334. hash -d A="/media/ayu/dearest"
    335. hash -d H="/media/data/backup/ayu"
    336. hash -d E="/etc/"
    337. hash -d D="/home/ayumi/Documents"
    338. #}}}
    339.  
    340. ##for Emacs {{{
    341. #在 Emacs终端 中使用 Zsh 的一些设置 不推荐在 Emacs 中使用它
    342. #if [[ "$TERM" == "dumb" ]]; then
    343. #setopt No_zle
    344. #PROMPT='%n@%M %/
    345. #>>'
    346. #alias ls='ls -F'
    347. #fi
    348. #}}}
    349.  
    350. #{{{自定义补全
    351. #补全 ping
    352. zstyle ':completion:*:ping:*' hosts 192.168.1.{1,50,51,100,101} www.google.com
    353.  
    354. #补全 ssh scp sftp 等
    355. #zstyle -e ':completion::*:*:*:hosts' hosts 'reply=(${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_}hosts(|2)(N) /dev/null)"}%%[# ]*}//,/ })'
    356. #}}}
    357.  
    358. #{{{ F1 计算器
    359. arith-eval-echo() {
    360. LBUFFER="${LBUFFER}echo \$(( "
    361. RBUFFER=" ))$RBUFFER"
    362. }
    363. zle -N arith-eval-echo
    364. bindkey "^[[11~" arith-eval-echo
    365. #}}}
    366.  
    367. ####{{{
    368. function timeconv { date -d @$1 +"%Y-%m-%d %T" }
    369.  
    370. # }}}
    371.  
    372. zmodload zsh/mathfunc
    373. autoload -U zsh-mime-setup
    374. zsh-mime-setup
    375. setopt EXTENDED_GLOB
    376. #autoload -U promptinit
    377. #promptinit
    378. #prompt redhat
    379.  
    380. setopt correctall
    381. autoload compinstall
    382.  
    383. #漂亮又实用的命令高亮界面
    384. setopt extended_glob
    385. TOKENS_FOLLOWED_BY_COMMANDS=('|' '||' ';' '&' '&&' 'sudo' 'do' 'time' 'strace')
    386.  
    387. recolor-cmd() {
    388. region_highlight=()
    389. colorize=true
    390. start_pos=0
    391. for arg in ${(z)BUFFER}; do
    392. ((start_pos+=${#BUFFER[$start_pos+1,-1]}-${#${BUFFER[$start_pos+1,-1]## #}}))
    393. ((end_pos=$start_pos+${#arg}))
    394. if $colorize; then
    395. colorize=false
    396. res=$(LC_ALL=C builtin type $arg 2>/dev/null)
    397. case $res in
    398. *'reserved word'*) style="fg=magenta,bold";;
    399. *'alias for'*) style="fg=cyan,bold";;
    400. *'shell builtin'*) style="fg=yellow,bold";;
    401. *'shell function'*) style='fg=green,bold';;
    402. *"$arg is"*)
    403. [[ $arg = 'sudo' ]] && style="fg=red,bold" || style="fg=blue,bold";;
    404. *) style='none,bold';;
    405. esac
    406. region_highlight+=("$start_pos $end_pos $style")
    407. fi
    408. [[ ${${TOKENS_FOLLOWED_BY_COMMANDS[(r)${arg//|/\|}]}:+yes} = 'yes' ]] && colorize=true
    409. start_pos=$end_pos
    410. done
    411. }
    412. check-cmd-self-insert() { zle .self-insert && recolor-cmd }
    413. check-cmd-backward-delete-char() { zle .backward-delete-char && recolor-cmd }
    414.  
    415. zle -N self-insert check-cmd-self-insert
    416. zle -N backward-delete-char check-cmd-backward-delete-char
 

shell自动补全功能:bash和zsh;zsh启动优化

 
转载

首要一点:shell有多种,比如bash、zsh、csh、ksh、sh、tcsh等

因此,制作自动补全功能时,要先搞清楚,你使用的是哪种shell,各个shell制作方法是不同的,网上大部分介绍的是关于bash的。

定义补全脚本后,要重新打开终端或者先执行下脚本:source

 

一、bash:

涉及命令:

补全命令complete、筛选命令compgen、修改补全命令设置compopt

内置变量:

通过这些变量,可以获得当前命令的内容、位置等信息,以便判断下面应该出现的提示命令的内容

除了上面三个命令外,Bash还有几个内置变量来辅助补全功能,如下: 

 

variabledescription
COMP_WORDS 类型为数组,存放当前命令行中输入的所有单词
COMP_CWORD 类型为整数,当前输入的单词在COMP_WORDS中的索引
COMPREPLY 类型为数组,候选的补全结果
COMP_WORDBREAKS 类型为字符串,表示单词之间的分隔符
COMP_LINE 类型为字符串,表示当前的命令行输入字符
COMP_POINT 类型为整数,表示光标在当前命令行的哪个位置

 

帮助信息:

man complete

补全脚本位置(Mac):

每打开一个新的shell,都会把这个目录下的脚本执行一遍

/usr/local/etc/bash_completion.d

代码解读:

复制代码
_god()
{
    COMPREPLY=()  # 为数组,名字必须是COMPREPLY,在给COMPREPLY赋值之前,最好将它重置清空,避免被其它补全函数干扰
    local cur prev
    _get_comp_words_by_ref cur prev
    COMPREPLY=( $( compgen -W 'xiaomi noops blog' -- "$cur" ) )
    return 0
} 
complete -F _god god
复制代码

 

_god()
{
    COMPREPLY=(xiaomi noops blog)
    return 0
}
complete -F _god god

 

查看已经有的命令补全:complete

 

最简单的使用方式:
complete -W "192.168.1.1 192.168.1.2" ssh
这样在输入ssh 后,按tab可以提示+补全IP地址

 

参考:

https://mp.weixin.qq.com/s/nSje0zhcP2vAmBAH05g64w

http://noops.me/?p=1114 

https://linux.cn/article-6301-1.html

 

二、zsh:

涉及命令:compctl

内置变量:没有bash的那些内置的变量,但是有个内置read函数,可以获取当前出现指令集、当前的指令内容、前一个指令内容等信息。

 

帮助信息:

通过这条命令查找zsh的内置函数,找到read的用法:

man zshbuiltins

read函数所用参数解释:

复制代码
-A     The first name is taken as the name of an array and all words are assigned to it.
-n     Together with -c, the number of the word the cursor is on is read.  With -l, the index of the character the cursor is on is read.  Note that the command name is word number 1, not word  0,  and
       that when the cursor is at the end of the line, its character index is the length of the line plus one.
-c
-l     These flags are allowed only if called inside a function used for completion (specified with the -K flag to compctl).  If the -c flag is given, the words of the current command are read. If the
       -l flag is given, the whole line is assigned as a scalar.  If both flags are present, -l is used and -c is ignored.
复制代码

 

man zsh

补全脚本位置(Mac):每个新的shell终端都会把这个脚本执行一遍,所以内容太多,一是占用内存,而是新的terminal启动慢

~/.zshrc

 

代码解读:执行下面这段代码,终端执行proxy命令,就可以看到提示信息

复制代码
_proxy(){
    local cur cword words  # 定义变量,cur表示当前光标下的单词
    read -cn cword  # 所有指令集
    read -Ac words  # 当前指令的索引值
    cur="$words[$cword-1]" # 当前指令值
    if [ $cur = "proxy" ]  # 根据当前不同指令返回对应的提示信息
    then
        reply=(start stop restart connect route help)  # 必须是值reply,返回提示信息内容
    elif [ $cur = "route" ]
    then
        reply=(add delete)
    else
        reply=()
    fi
}
compctl -K _proxy proxy   # -K 表示使用函数
复制代码

 

参考:

https://github.com/johan/zsh/blob/master/Misc/compctl-examples

 

在.zshrc里加入如下语句:意思大概是自动加载fpath路径下的各种函数,比如自动补全函数。

fpath=(/usr/local/share/zsh-completions $fpath)
autoload -Uz compinit && compinit -u
autoload -U +X bashcompinit && bashcompinit

另外autoload/compinit/bashcompinit是zsh的builtin函数,可以使用man zshbuiltins查看帮助

三、brew search comple

这种模糊搜索可以查到很多工具的命令自动补全脚本:比如pip、bash、docker、zsh等

 

brew info bash-completion查看安装信息

四、python shell的自动补全

五、zsh启动优化

查看zsh启动时间:2.37s,还是很长的,是否可以优化到0.x秒,这样感觉就没有卡顿

time zsh -i -c exit
zsh -i -c exit  2.37s user 1.25s system 98% cpu 3.663 total

在 Fedora 系统上设置 zsh

对于一些人来说,终端可能会很吓人。但终端不仅仅是一个输入的黑屏。它通常运行一个 shell(外壳),如此称呼的原因是它围绕着内核。shell 是一个基于文本的界面,可让你在系统上运行命令。它有时也被称为 命令行解释器(command line interpreter)(CLI)。与大多数 Linux 发行版一样,Fedora 带有 bash 作为默认 shell。但是,它不是唯一可用的 shell,你可以安装其他的 shell。本文重点介绍 Z Shell (即 zsh)。

Bash 是对 UNIX 中提供的旧式 Bourne shell(sh)的重写(LCTT 译注:Bourne Again SHell)。zsh 视图通过更好的交互以比 bash 更友善。它的一些有用功能是:

  • 可编程的命令行补全 * 在运行的 shell 会话之间共享命令历史 * 拼写纠正 * 可加载模块 * 交互式选择文件和文件夹

zsh 在 Fedora 仓库中存在。要安装,请运行以下命令:

$ sudo dnf install zsh

使用 zsh

要开始使用它,只需输入 zsh,新的 shell 在第一次运行时显示向导。该向导可帮助你配置初始功能,如历史记录行为和自动补全。或者你可以选择保持 rc 文件 为空:

 

 

zsh First Run Wizzard

如果输入 1,则启动配置向导。其他选项立即启动 shell。

请注意,用户提示符是  而不是与 bash 的 $。这里的一个重要功能是自动补全功能,它允许你使用 Tab 键在文件和目录之间移动,非常类似于菜单:

 

 

zsh cd Feature

另一个有趣的功能是拼写纠正,这有助于在混合大小写的情况下输入文件名:

 

 

zsh Auto Completion

使用 zsh 成为你的默认 shell


zsh 提供了很多插件,如 zsh-syntax-highlighting 和著名的 “Oh my zsh”(在此查看其页面)。也许你希望将其设为默认 shell,以便在你在开始会话或打开终端时运行。为此,请使用 chsh(“更改 shell”)命令:

$ chsh -s $(which zsh)

这个命令告诉你的系统你要设置(-s)默认 shell 为该 shell 的正确位置(which zsh)。

图片来自 Flickr 由 Kate Ter Haar 提供(CC BY-SA)。

via: 

 

将美化进行到底,把 PowerShell 做成 oh-my-zsh 的样子

 

不知你有没有看过 Linux 上 oh-my-zsh 的样子?看过之后你一定会惊叹,原来命令行还能这么玩!然而 Windows 下能这么玩吗?答案是可行的,接下来就来看看怎么玩。

借用了下 oh-my-zsh 的官网图片


Windows 下我们用 oh-my-posh 在 PowerShell 中实现这样的效果。分以下三步走:

 

本文内容

 

安装 oh-my-posh

我们需要先以管理员权限启动 PowerShell,以便执行安装操作。(具体是在开始按钮上点击右键,选择“Windows PowerShell (管理员)”。)

以管理员权限启动 PowerShell

然后,运行命令以安装 posh-git,这是 oh-my-posh 的依赖。

Install-Module posh-git -Scope CurrentUser

如果此前没有安装 NuGet 提供程序,则此时会提示安装 NuGet;如果此前没有开启执行任意脚本,此处也会提示执行脚本。如果没有权限执行脚本,可能需要先执行 Set-ExecutionPolicy Bypass

Install-Module posh-git -Scope CurrentUser

安装 NuGet 提供程序

安装 posh-git

接下来,运行命令以安装 oh-my-posh 本身。

Install-Module oh-my-posh -Scope CurrentUser

Install-Module oh-my-posh -Scope CurrentUser

安装 oh-my-posh

自此,oh-my-posh 安装完毕。

启用模组并设置主题

接下来,我们需要启用安装的模组。启用模组的命令是:

Import-Module oh-my-posh

其实写本文主要就是想体验 zsh 的操作,并看看 git 文件夹的视觉效果。现在我们就试试,输入:

Set-PoshPrompt

(注意,oh-my-posh 更新后,命令从 Set-Theme 变成了 Set-PoshPrompt。)

然后按一下空格,按一下 Tab。会发现这时已经可以用方向键来选择参数了!原生 PowerShell 可没有这个功能啊!

选择主题

我们选择 Agnoster 主题。(这些主题都是 oh-my-posh 带给我们的。)

接下来我们看看 git 文件夹下的显示:

git 文件夹的显示

并没有 zsh 那样的效果。——因为我们缺少专用的字体!

下一节我们会讲如何安装专为 zsh 效果设计的字体。

现在,我们需要让 PowerShell 每次启动的时候都能够加载这个模组,所以我们需要设置 profile 文件让它自动启用。

敲 $profile 可以让 PowerShell 告诉我们这个文件的路径是什么。当然下图是我的路径,读者的默认在文档路径里的 PowerShell 文件夹下。

profile 文件路径

我们需要编辑这个文件(如果没有,手动创建一个),然后在里面写下那一句话:

Import-Module oh-my-posh
Set-PoshPrompt Paradox

在个人配置文件中的内容

接下来,新打开 PowerShell(不需要管理员权限)时就会提示加载了这个文件:

加载个人及系统配置文件

安装字体/安装第三方 PowerShell

!!!重要说明:给 PowerShell 定制字体是一件非常困难的事情,非常困难!!! 可参见 自定义 Windows PowerShell 和 cmd 的字体 感受一下。 所以,这里更倾向于在安装了字体的情况下使用第三方 PowerShell。

比如下图是我用 vscode 中带的 PowerShell 的效果。

PowerShell in vscode

推荐的其他 PowerShell:

但是,如果你执意要跑原生 PowerShell,那也不是没有办法,你可以使用 PowerLine 专为 PowerShell 和 zsh 设计的字体,它们的字体是可以完美跑到 PowerShell 和 PowerShell Core 中的。

下图是我在 PowerShell Core 中的运行效果:

PowerLine 字体效果

请在这里下载 PowerLine 字体:

方法是克隆这个仓库,然后在克隆出来的文件夹中找到 Install.ps1 文件,执行它,会发现它会自动为我们安装所有的 PowerLine 字体。

Install.ps1

安装所有的字体

安装完成之后,在 PowerShell 或者 PowerShell Core 的标题栏上右击选择“属性”,然后选择你想要设置的字体就可以立刻看到效果了。注意,PowerLine 字体都是带有 for PowerLine 后缀的。

设置字体

PowerLine 字体官方文档在这里:Overview — Powerline beta documentation

官方文档中的 PowerLine 字体截图
▲ 官方文档中的 PowerLine 字体截图


参考资料

本文会经常更新,请阅读原文: https://blog.walterlv.com/post/beautify-powershell-like-zsh.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

posted @ 2021-04-10 12:08  CharyGao  阅读(2631)  评论(0)    收藏  举报