终极 Shell——ZSH

Shell是Linux/Unix的一个外壳,你理解成衣服也行。它负责外界与Linux内核的交互,接收用户或其他应用程序的命令,然后把这些命令转化成内核能理解的语言,传给内核,内核是真正干活的,干完之后再把结果返回用户或应用程序。

Linux/Unix提供了很多种Shell,为毛要这么多Shell?难道用来炒着吃么?那我问你,你同类型的衣服怎么有那么多件?花色,质地还不一样。写程序比买衣服复杂多了,而且程序员往往负责把复杂的事情搞简单,简单的事情搞复杂。牛程序员看到不爽的Shell,就会自己重新写一套,慢慢形成了一些标准,常用的Shell有这么几种,sh、bash、csh等,想知道你的系统有几种shell,可以通过以下命令查看:

cat /etc/shells

显示如下:

/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh

在 Linux 里执行这个命令和 Mac 略有不同,你会发现 Mac 多了一个 zsh,也就是说 OS X 系统预装了个 zsh,这是个神马 Shell 呢?

目前常用的 Linux 系统和 OS X 系统的默认 Shell 都是 bash,但是真正强大的 Shell 是深藏不露的 zsh, 这货绝对是马车中的跑车,跑车中的飞行车,史称『终极 Shell』,但是由于配置过于复杂,所以初期无人问津,很多人跑过来看看 zsh 的配置指南,什么都不说转身就走了。直到有一天,国外有个穷极无聊的程序员开发出了一个能够让你快速上手的zsh项目,叫做「oh my zsh」,Github 网址是:github.com/robbyrussell。这玩意就像「X天叫你学会 C++」系列,可以让你神功速成,而且是真的。

好,下面我们看看如何安装、配置和使用 zsh。

安装zsh

如果你用 Mac,就可以直接看下一节
如果你用 Redhat Linux,执行:sudo yum install zsh
如果你用 Ubuntu Linux,执行:sudo apt-get install zsh
如果你用 Windows……去洗洗睡吧。

安装完成后设置当前用户使用 zsh:chsh -s /bin/zsh,根据提示输入当前用户的密码就可以了。

安装oh my zsh

首先安装 Git,安装方式同上,把 zsh 换成 git 即可。

安装「oh my zsh」可以自动安装也可以手动安装。

自动安装:

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

手动安装:

git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc

都不复杂,安装完成之后退出当前会话重新打开一个终端窗口,你就可以见到这个彩色的提示了:


配置

zsh 的配置主要集中在用户当前目录的.zshrc里,用 vim 或你喜欢的其他编辑器打开.zshrc,在最下面会发现这么一行字:

# Customize to your needs…

可以在此处定义自己的环境变量和别名,当然,oh my zsh 在安装时已经自动读取当前的环境变量并进行了设置,你可以继续追加其他环境变量。

接下来进行别名的设置,我自己的部分配置如下:

  1. alias cls='clear'  
  2. alias ll='ls -l'  
  3. alias la='ls -a'  
  4. alias vi='vim'  
  5. alias javac="javac -J-Dfile.encoding=utf8"  
  6. alias grep="grep --color=auto"  
  7. alias -s html=mate   # 在命令行直接输入后缀为 html 的文件名,会在 TextMate 中打开  
  8. alias -s rb=mate     # 在命令行直接输入 ruby 文件,会在 TextMate 中打开  
  9. alias -s py=vi       # 在命令行直接输入 python 文件,会用 vim 中打开,以下类似  
  10. alias -s js=vi  
  11. alias -s c=vi  
  12. alias -s java=vi  
  13. alias -s txt=vi  
  14. alias -s gz='tar -xzvf'  
  15. alias -s tgz='tar -xzvf'  
  16. alias -s zip='unzip'  
  17. alias -s bz2='tar -xjvf'  
  18. #color{{{  
  19. autoload colors  
  20. colors  
  21.    
  22. for color in RED GREEN YELLOW BLUE MAGENTA CYAN WHITE; do  
  23. eval _$color='%{$terminfo[bold]$fg[${(L)color}]%}'  
  24. eval $color='%{$fg[${(L)color}]%}'  
  25. (( count = $count + 1 ))  
  26. done  
  27. FINISH="%{$terminfo[sgr0]%}"  
  28. #}}}  
  29.    
  30. #命令提示符  
  31. RPROMPT=$(echo "$RED%D %T$FINISH")  
  32. PROMPT=$(echo "$CYAN%n@$YELLOW%M:$GREEN%/$_YELLOW>$FINISH ")  
  33.    
  34. #PROMPT=$(echo "$BLUE%M$GREEN%/  
  35. #$CYAN%n@$BLUE%M:$GREEN%/$_YELLOW>>>$FINISH ")  
  36. #标题栏、任务栏样式{{{  
  37. case $TERM in (*xterm*|*rxvt*|(dt|k|E)term)  
  38. precmd () { print -Pn "\e]0;%n@%M//%/\a" }  
  39. preexec () { print -Pn "\e]0;%n@%M//%/\ $1\a" }  
  40. ;;  
  41. esac  
  42. #}}}  
  43.    
  44. #编辑器  
  45. export EDITOR=vim  
  46. #输入法  
  47. export XMODIFIERS="@im=ibus"  
  48. export QT_MODULE=ibus  
  49. export GTK_MODULE=ibus  
  50. #关于历史纪录的配置 {{{  
  51. #历史纪录条目数量  
  52. export HISTSIZE=10000  
  53. #注销后保存的历史纪录条目数量  
  54. export SAVEHIST=10000  
  55. #历史纪录文件  
  56. export HISTFILE=~/.zhistory  
  57. #以附加的方式写入历史纪录  
  58. setopt INC_APPEND_HISTORY  
  59. #如果连续输入的命令相同,历史纪录中只保留一个  
  60. setopt HIST_IGNORE_DUPS  
  61. #为历史纪录中的命令添加时间戳  
  62. setopt EXTENDED_HISTORY        
  63.    
  64. #启用 cd 命令的历史纪录,cd -[TAB]进入历史路径  
  65. setopt AUTO_PUSHD  
  66. #相同的历史路径只保留一个  
  67. setopt PUSHD_IGNORE_DUPS  
  68.    
  69. #在命令前添加空格,不将此命令添加到纪录文件中  
  70. #setopt HIST_IGNORE_SPACE  
  71. #}}}  
  72.    
  73. #每个目录使用独立的历史纪录{{{  
  74. cd() {  
  75. builtin cd "$@"                             # do actual cd  
  76. fc -W                                       # write current history  file  
  77. local HISTDIR="$HOME/.zsh_history$PWD"      # use nested folders for history  
  78. if  [ ! -d "$HISTDIR" ] ; then          # create folder if needed  
  79. mkdir -p "$HISTDIR"  
  80. fi  
  81. export HISTFILE="$HISTDIR/zhistory"     # set new history file  
  82. touch $HISTFILE  
  83. local ohistsize=$HISTSIZE  
  84. HISTSIZE=0                              # Discard previous dir's history  
  85. HISTSIZE=$ohistsize                     # Prepare for new dir's history  
  86. fc -R                                       #read from current histfile  
  87. }  
  88. mkdir -p $HOME/.zsh_history$PWD  
  89. export HISTFILE="$HOME/.zsh_history$PWD/zhistory"  
  90.    
  91. function allhistory { cat $(find $HOME/.zsh_history -name zhistory) }  
  92. function convhistory {  
  93. sort $1 | uniq |  
  94. sed 's/^:[09]:[0-9]*;./\1::::::\2/' |  
  95. awk -F"::::::" '{ $1=strftime("%Y-%m-%d %T",$1) "|"; print }'  
  96. }  
  97. #使用 histall 命令查看全部历史纪录  
  98. function histall { convhistory =(allhistory) |  
  99. sed '/^.\{20\} *cd/i\\' }  
  100. #使用 hist 查看当前目录历史纪录  
  101. function hist { convhistory $HISTFILE }  
  102.    
  103. #全部历史纪录 top50  
  104. 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 }  
  105.    
  106. #}}}  
  107.    
  108. #杂项 {{{  
  109. #允许在交互模式中使用注释  例如:  
  110. #cmd #这是注释  
  111. setopt INTERACTIVE_COMMENTS        
  112.    
  113. #启用自动 cd,输入目录名回车进入目录  
  114. #稍微有点混乱,不如 cd 补全实用  
  115. setopt AUTO_CD  
  116.    
  117. #扩展路径  
  118. #/v/c/p/p => /var/cache/pacman/pkg  
  119. setopt complete_in_word  
  120.    
  121. #禁用 core dumps  
  122. limit coredumpsize 0  
  123.    
  124. #Emacs风格 键绑定  
  125. bindkey -e  
  126. #bindkey -v  
  127. #设置 [DEL]键 为向后删除  
  128. #bindkey "\e[3~" delete-char  
  129.    
  130. #以下字符视为单词的一部分  
  131. WORDCHARS='*?_-[]~=&;!#$%^(){}<>'  
  132. #}}}  
  133.    
  134. #自动补全功能 {{{  
  135. setopt AUTO_LIST  
  136. setopt AUTO_MENU  
  137. #开启此选项,补全时会直接选中菜单项  
  138. #setopt MENU_COMPLETE  
  139.    
  140. autoload -U compinit  
  141. compinit  
  142.    
  143. #自动补全缓存  
  144. #zstyle ':completion::complete:*' use-cache on  
  145. #zstyle ':completion::complete:*' cache-path .zcache  
  146. #zstyle ':completion:*:cd:*' ignore-parents parent pwd  
  147.    
  148. #自动补全选项  
  149. zstyle ':completion:*' verbose yes  
  150. zstyle ':completion:*' menu select  
  151. zstyle ':completion:*:*:default' force-list always  
  152. zstyle ':completion:*' select-prompt '%SSelect:  lines: %L  matches: %M  [%p]'  
  153.    
  154. zstyle ':completion:*:match:*' original only  
  155. zstyle ':completion::prefix-1:*' completer _complete  
  156. zstyle ':completion:predict:*' completer _complete  
  157. zstyle ':completion:incremental:*' completer _complete _correct  
  158. zstyle ':completion:*' completer _complete _prefix _correct _prefix _match _approximate  
  159.    
  160. #路径补全  
  161. zstyle ':completion:*' expand 'yes'  
  162. zstyle ':completion:*' squeeze-shlashes 'yes'  
  163. zstyle ':completion::complete:*' '\\'  
  164.    
  165. #彩色补全菜单  
  166. eval $(dircolors -b)  
  167. export ZLSCOLORS="${LS_COLORS}"  
  168. zmodload zsh/complist  
  169. zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}  
  170. zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'  
  171.    
  172. #修正大小写  
  173. zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}'  
  174. #错误校正  
  175. zstyle ':completion:*' completer _complete _match _approximate  
  176. zstyle ':completion:*:match:*' original only  
  177. zstyle ':completion:*:approximate:*' max-errors 1 numeric  
  178.    
  179. #kill 命令补全  
  180. compdef pkill=kill  
  181. compdef pkill=killall  
  182. zstyle ':completion:*:*:kill:*' menu yes select  
  183. zstyle ':completion:*:*:*:*:processes' force-list always  
  184. zstyle ':completion:*:processes' command 'ps -au$USER'  
  185.    
  186. #补全类型提示分组  
  187. zstyle ':completion:*:matches' group 'yes'  
  188. zstyle ':completion:*' group-name ''  
  189. zstyle ':completion:*:options' description 'yes'  
  190. zstyle ':completion:*:options' auto-description '%d'  
  191. zstyle ':completion:*:descriptions' format $'\e[01;33m -- %d --\e[0m'  
  192. zstyle ':completion:*:messages' format $'\e[01;35m -- %d --\e[0m'  
  193. zstyle ':completion:*:warnings' format $'\e[01;31m -- No Matches Found --\e[0m'  
  194. zstyle ':completion:*:corrections' format $'\e[01;32m -- %d (errors: %e) --\e[0m'  
  195.    
  196. # cd ~ 补全顺序  
  197. zstyle ':completion:*:-tilde-:*' group-order 'named-directories' 'path-directories' 'users' 'expand'  
  198. #}}}  
  199.    
  200. ##行编辑高亮模式 {{{  
  201. # Ctrl+@ 设置标记,标记和光标点之间为 region  
  202. zle_highlight=(region:bg=magenta #选中区域  
  203. special:bold      #特殊字符  
  204. isearch:underline)#搜索时使用的关键字  
  205. #}}}  
  206.    
  207. ##空行(光标在行首)补全 "cd " {{{  
  208. user-complete(){  
  209. case $BUFFER in  
  210. "" )                       # 空行填入 "cd "  
  211. BUFFER="cd "  
  212. zle end-of-line  
  213. zle expand-or-complete  
  214. ;;  
  215. "cd --" )                  # "cd --" 替换为 "cd +"  
  216. BUFFER="cd +"  
  217. zle end-of-line  
  218. zle expand-or-complete  
  219. ;;  
  220. "cd +-" )                  # "cd +-" 替换为 "cd -"  
  221. BUFFER="cd -"  
  222. zle end-of-line  
  223. zle expand-or-complete  
  224. ;;  
  225. * )  
  226. zle expand-or-complete  
  227. ;;  
  228. esac  
  229. }  
  230. zle -N user-complete  
  231. bindkey "\t" user-complete  
  232. #}}}  
  233.    
  234. ##在命令前插入 sudo {{{  
  235. #定义功能  
  236. sudo-command-line() {  
  237. [[ -z $BUFFER ]] && zle up-history  
  238. [[ $BUFFER != sudo\ * ]] && BUFFER="sudo $BUFFER"  
  239. zle end-of-line                 #光标移动到行末  
  240. }  
  241. zle -N sudo-command-line  
  242. #定义快捷键为: [Esc] [Esc]  
  243. bindkey "\e\e" sudo-command-line  
  244. #}}}  
  245.    
  246. #命令别名 {{{  
  247. alias cp='cp -i'  
  248. alias mv='mv -i'  
  249. alias rm='rm -i'  
  250. alias ls='ls -F --color=auto'  
  251. alias ll='ls -al'  
  252. alias grep='grep --color=auto'  
  253. alias la='ls -a'  
  254. alias pacman='sudo pacman-color'  
  255. alias p='sudo pacman-color'  
  256. alias y='yaourt'  
  257. alias h='htop'  
  258. alias vim='sudo vim'  
  259.    
  260. #[Esc][h] man 当前命令时,显示简短说明  
  261. alias run-help >&/dev/null && unalias run-help  
  262. autoload run-help  
  263.    
  264. #历史命令 top10  
  265. alias top10='print -l  ${(o)history%% *} | uniq -c | sort -nr | head -n 10'  
  266. #}}}  
  267.    
  268. #路径别名 {{{  
  269. #进入相应的路径时只要 cd ~xxx  
  270. hash -d A="/media/ayu/dearest"  
  271. hash -d H="/media/data/backup/ayu"  
  272. hash -d E="/etc/"  
  273. hash -d D="/home/ayumi/Documents"  
  274. #}}}  
  275.    
  276. ##for Emacs {{{  
  277. #在 Emacs终端 中使用 Zsh 的一些设置 不推荐在 Emacs 中使用它  
  278. #if [[ "$TERM" == "dumb" ]]; then  
  279. #setopt No_zle  
  280. #PROMPT='%n@%M %/  
  281. #>>'  
  282. #alias ls='ls -F'  
  283. #fi  
  284. #}}}  
  285.    
  286. #{{{自定义补全  
  287. #补全 ping  
  288. zstyle ':completion:*:ping:*' hosts 192.168.1.{1,50,51,100,101} www.google.com  
  289.    
  290. #补全 ssh scp sftp 等  
  291. #zstyle -e ':completion::*:*:*:hosts' hosts 'reply=(${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_}hosts(|2)(N) /dev/null)"}%%[# ]*}//,/ })'  
  292. #}}}  
  293.    
  294. #{{{ F1 计算器  
  295. arith-eval-echo() {  
  296. LBUFFER="${LBUFFER}echo \$(( "  
  297. RBUFFER=" ))$RBUFFER"  
  298. }  
  299. zle -N arith-eval-echo  
  300. bindkey "^[[11~" arith-eval-echo  
  301. #}}}  
  302.    
  303. ####{{{  
  304. function timeconv { date -d @$1 +"%Y-%m-%d %T" }  
  305.    
  306. # }}}  
  307.    
  308. zmodload zsh/mathfunc  
  309. autoload -U zsh-mime-setup  
  310. zsh-mime-setup  
  311. setopt EXTENDED_GLOB  
  312. #autoload -U promptinit  
  313. #promptinit  
  314. #prompt redhat  
  315.    
  316. setopt correctall  
  317. autoload compinstall  
  318.    
  319. #漂亮又实用的命令高亮界面  
  320. setopt extended_glob  
  321.  TOKENS_FOLLOWED_BY_COMMANDS=('|' '||' ';' '&' '&&' 'sudo' 'do' 'time' 'strace')  
  322.    
  323.  recolor-cmd() {  
  324.      region_highlight=()  
  325.      colorize=true  
  326.      start_pos=0  
  327.      for arg in ${(z)BUFFER}; do  
  328.          ((start_pos+=${#BUFFER[$start_pos+1,-1]}-${#${BUFFER[$start_pos+1,-1]## #}}))  
  329.          ((end_pos=$start_pos+${#arg}))  
  330.          if $colorize; then  
  331.              colorize=false  
  332.              res=$(LC_ALL=C builtin type $arg 2>/dev/null)  
  333.              case $res in  
  334.                  *'reserved word'*)   style="fg=magenta,bold";;  
  335.                  *'alias for'*)       style="fg=cyan,bold";;  
  336.                  *'shell builtin'*)   style="fg=yellow,bold";;  
  337.                  *'shell function'*)  style='fg=green,bold';;  
  338.                  *"$arg is"*)  
  339.                      [[ $arg = 'sudo' ]] && style="fg=red,bold" || style="fg=blue,bold";;  
  340.                  *)                   style='none,bold';;  
  341.              esac  
  342.              region_highlight+=("$start_pos $end_pos $style")  
  343.          fi  
  344.          [[ ${${TOKENS_FOLLOWED_BY_COMMANDS[(r)${arg//|/\|}]}:+yes} = 'yes' ]] && colorize=true  
  345.          start_pos=$end_pos  
  346.      done  
  347.  }  
  348. check-cmd-self-insert() { zle .self-insert && recolor-cmd }  
  349.  check-cmd-backward-delete-char() { zle .backward-delete-char && recolor-cmd }  
  350.    
  351.  zle -N self-insert check-cmd-self-insert  
  352.  zle -N backward-delete-char check-cmd-backward-delete-char   
  1. # man page highlight  
  2. export LESS_TERMCAP_mb=$'\E[01;31m'       # begin blinking  
  3. export LESS_TERMCAP_md=$'\E[01;38;5;74m'  # begin bold  
  4. export LESS_TERMCAP_me=$'\E[0m'           # end mode  
  5. export LESS_TERMCAP_se=$'\E[0m'           # end standout-mode  
  6. export LESS_TERMCAP_so=$'\E[38;5;246m'    # begin standout-mode - info box  
  7. export LESS_TERMCAP_ue=$'\E[0m'           # end underline  
  8. export LESS_TERMCAP_us=$'\E[04;38;5;146m' # begin underline  

zsh 的牛粪之处在于不仅可以设置通用别名,还能针对文件类型设置对应的打开程序,比如:

alias -s html=mate,意思就是你在命令行输入 hello.html,zsh会为你自动打开 TextMat 并读取 hello.html; alias -s gz='tar -xzvf',表示自动解压后缀为 gz 的压缩包。

总之,只有想不到,木有做不到。

设置完环境变量和别名之后,基本上就可以用了,如果你是个主题控,还可以玩玩 zsh 的主题。在 .zshrc 里找到ZSH_THEME,就可以设置主题了,默认主题是:

ZSH_THEME=”robbyrussell”

oh my zsh 提供了数十种主题,相关文件在~/.oh-my-zsh/themes目录下,你可以随意选择,也可以编辑主题满足自己的变态需求,我采用了默认主题robbyrussell,不过做了一点小小的改动:

PROMPT='%{$fg_bold[red]%}➜ %{$fg_bold[green]%}%p%{$fg[cyan]%}%d %{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%}% %{$reset_color%}>'
#PROMPT='%{$fg_bold[red]%}➜ %{$fg_bold[green]%}%p %{$fg[cyan]%}%c %{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%} % %{$reset_color%}'

对照原来的版本,我把 c 改为 d,c 表示当前目录,d 表示绝对路径,另外在末尾增加了一个「 > 」,改完之后的效果是这样的:

大家可以尝试进行改造,也算个趣事。

最后我们来说说插件。

插件

oh my zsh 项目提供了完善的插件体系,相关的文件在~/.oh-my-zsh/plugins目录下,默认提供了100多种,大家可以根据自己的实际学习和工作环境采用,想了解每个插件的功能,只要打开相关目录下的 zsh 文件看一下就知道了。插件也是在.zshrc里配置,找到plugins关键字,你就可以加载自己的插件了,系统默认加载 git ,你可以在后面追加内容,如下:

plugins=(git textmate ruby autojump osx mvn gradle)

下面简单介绍几个:

1、git:当你处于一个 git 受控的目录下时,Shell 会明确显示 「git」和 branch,如上图所示,另外对 git 很多命令进行了简化,例如 gco=’git checkout’、gd=’git diff’、gst=’git status’、g=’git’等等,熟练使用可以大大减少 git 的命令长度,命令内容可以参考~/.oh-my-zsh/plugins/git/git.plugin.zsh

2、textmate:mr可以创建 ruby 的框架项目,tm finename 可以用 textmate 打开指定文件。

3、osx:tab 增强,quick-look filename 可以直接预览文件,man-preview grep 可以生成 grep手册 的pdf 版本等。

4、autojump:zsh 和 autojump 的组合形成了 zsh 下最强悍的插件,今天我们主要说说这货。

首先安装autojump,如果你用 Mac,可以使用 brew 安装:

brew install autojump

如果是 Linux,去下载 autojump 的最新版本,比如:

wget https://github.com/downloads/joelthelion/autojump/autojump_v21.1.2.tar.gz

解压缩后进入目录,执行

./install.sh

最后把以下代码加入.zshrc:

[[ -s ~/.autojump/etc/profile.d/autojump.sh ]] && . ~/.autojump/etc/profile.d/autojump.sh

至此,安装、配置、插件三位一体,终极 Shell 全面登场。退出终端会话重新登录,开始感受 zsh 的训疾如风!

使用 zsh

1、兼容 bash,原来使用 bash 的兄弟切换过来毫无压力,该咋用咋用。

2、强大的历史纪录功能,输入 grep 然后用上下箭头可以翻阅你执行的所有 grep 命令。

3、智能拼写纠正,输入gtep mactalk * -R,系统会提示:zsh: correct ‘gtep’ to ‘grep’ [nyae]? 比妹纸贴心吧,她们向来都是让你猜的……

4、各种补全:路径补全、命令补全,命令参数补全,插件内容补全等等。触发补全只需要按一下或两下 tab 键,补全项可以使用 ctrl+n/p/f/b上下左右切换。比如你想杀掉 Java 的进程,只需要输入 kill java + tab键,如果只有一个 java 进程,zsh 会自动替换为进程的 pid,如果有多个则会出现选择项供你选择。ssh + 空格 + 两个tab键,zsh会列出所有访问过的主机和用户名进行补全

5、智能跳转,安装了autojump之后,zsh 会自动记录你访问过的目录,通过 j + 目录名 可以直接进行目录跳转,而且目录名支持模糊匹配和自动补全,例如你访问过Hadoop-1.0.0目录,输入j hado 即可正确跳转。j –stat 可以看你的历史路径库。

6、目录浏览和跳转:输入 d,即可列出你在这个会话里访问的目录列表,输入列表前的序号,即可直接跳转。

7、在当前目录下输入 .. 或 … ,或直接输入当前目录名都可以跳转,你甚至不再需要输入 cd 命令了。

8、通配符搜索:ls -l **/*.sh,可以递归显示当前目录下的 shell 文件,文件少时可以代替 find,文件太多就歇菜了。

9、更强的别名:请参考配置一节。

10、插件支持:请参考插件一节。

print?
  1. alias cls='clear' 
  2. alias ll='ls -l' 
  3. alias la='ls -a' 
  4. alias vi='vim' 
  5. alias javac="javac -J-Dfile.encoding=utf8" 
  6. alias grep="grep --color=auto" 
  7. alias -s html=mate   # 在命令行直接输入后缀为 html 的文件名,会在 TextMate 中打开 
  8. alias -s rb=mate     # 在命令行直接输入 ruby 文件,会在 TextMate 中打开 
  9. alias -s py=vi       # 在命令行直接输入 python 文件,会用 vim 中打开,以下类似 
  10. alias -s js=vi 
  11. alias -s c=vi 
  12. alias -s java=vi 
  13. alias -s txt=vi 
  14. alias -s gz='tar -xzvf' 
  15. alias -s tgz='tar -xzvf' 
  16. alias -s zip='unzip' 
  17. alias -s bz2='tar -xjvf' 
  18. #color{{{ 
  19. autoload colors 
  20. colors 
  21.   
  22. for color in RED GREEN YELLOW BLUE MAGENTA CYAN WHITE; do 
  23. eval _$color='%{$terminfo[bold]$fg[${(L)color}]%}' 
  24. eval $color='%{$fg[${(L)color}]%}' 
  25. (( count = $count + 1 )) 
  26. done 
  27. FINISH="%{$terminfo[sgr0]%}" 
  28. #}}} 
  29.   
  30. #命令提示符 
  31. RPROMPT=$(echo "$RED%D %T$FINISH") 
  32. PROMPT=$(echo "$CYAN%n@$YELLOW%M:$GREEN%/$_YELLOW>$FINISH ") 
  33.   
  34. #PROMPT=$(echo "$BLUE%M$GREEN%/ 
  35. #$CYAN%n@$BLUE%M:$GREEN%/$_YELLOW>>>$FINISH ") 
  36. #标题栏、任务栏样式{{{ 
  37. case $TERM in (*xterm*|*rxvt*|(dt|k|E)term) 
  38. precmd () { print -Pn "\e]0;%n@%M//%/\a" } 
  39. preexec () { print -Pn "\e]0;%n@%M//%/\ $1\a" } 
  40. ;; 
  41. esac 
  42. #}}} 
  43.   
  44. #编辑器 
  45. export EDITOR=vim 
  46. #输入法 
  47. export XMODIFIERS="@im=ibus" 
  48. export QT_MODULE=ibus 
  49. export GTK_MODULE=ibus 
  50. #关于历史纪录的配置 {{{ 
  51. #历史纪录条目数量 
  52. export HISTSIZE=10000 
  53. #注销后保存的历史纪录条目数量 
  54. export SAVEHIST=10000 
  55. #历史纪录文件 
  56. export HISTFILE=~/.zhistory 
  57. #以附加的方式写入历史纪录 
  58. setopt INC_APPEND_HISTORY 
  59. #如果连续输入的命令相同,历史纪录中只保留一个 
  60. setopt HIST_IGNORE_DUPS 
  61. #为历史纪录中的命令添加时间戳 
  62. setopt EXTENDED_HISTORY       
  63.   
  64. #启用 cd 命令的历史纪录,cd -[TAB]进入历史路径 
  65. setopt AUTO_PUSHD 
  66. #相同的历史路径只保留一个 
  67. setopt PUSHD_IGNORE_DUPS 
  68.   
  69. #在命令前添加空格,不将此命令添加到纪录文件中 
  70. #setopt HIST_IGNORE_SPACE 
  71. #}}} 
  72.   
  73. #每个目录使用独立的历史纪录{{{ 
  74. cd() { 
  75. builtin cd "$@"                             # do actual cd 
  76. fc -W                                       # write current history  file 
  77. local HISTDIR="$HOME/.zsh_history$PWD"      # use nested folders for history 
  78. if  [ ! -d "$HISTDIR" ] ; then          # create folder if needed 
  79. mkdir -p "$HISTDIR" 
  80. fi 
  81. export HISTFILE="$HISTDIR/zhistory"     # set new history file 
  82. touch $HISTFILE 
  83. local ohistsize=$HISTSIZE 
  84. HISTSIZE=0                              # Discard previous dir's history 
  85. HISTSIZE=$ohistsize                     # Prepare for new dir's history 
  86. fc -R                                       #read from current histfile 
  87. mkdir -p $HOME/.zsh_history$PWD 
  88. export HISTFILE="$HOME/.zsh_history$PWD/zhistory" 
  89.   
  90. function allhistory { cat $(find $HOME/.zsh_history -name zhistory) } 
  91. function convhistory { 
  92. sort $1 | uniq | 
  93. sed 's/^:[09]:[0-9]*;./\1::::::\2/' | 
  94. awk -F"::::::" '{ $1=strftime("%Y-%m-%d %T",$1) "|"; print }' 
  95. #使用 histall 命令查看全部历史纪录 
  96. function histall { convhistory =(allhistory) | 
  97. sed '/^.\{20\} *cd/i\\' } 
  98. #使用 hist 查看当前目录历史纪录 
  99. function hist { convhistory $HISTFILE } 
  100.   
  101. #全部历史纪录 top50 
  102. 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 } 
  103.   
  104. #}}} 
  105.   
  106. #杂项 {{{ 
  107. #允许在交互模式中使用注释  例如: 
  108. #cmd #这是注释 
  109. setopt INTERACTIVE_COMMENTS       
  110.   
  111. #启用自动 cd,输入目录名回车进入目录 
  112. #稍微有点混乱,不如 cd 补全实用 
  113. setopt AUTO_CD 
  114.   
  115. #扩展路径 
  116. #/v/c/p/p => /var/cache/pacman/pkg 
  117. setopt complete_in_word 
  118.   
  119. #禁用 core dumps 
  120. limit coredumpsize 0 
  121.   
  122. #Emacs风格 键绑定 
  123. bindkey -e 
  124. #bindkey -v 
  125. #设置 [DEL]键 为向后删除 
  126. #bindkey "\e[3~" delete-char 
  127.   
  128. #以下字符视为单词的一部分 
  129. WORDCHARS='*?_-[]~=&;!#$%^(){}<>' 
  130. #}}} 
  131.   
  132. #自动补全功能 {{{ 
  133. setopt AUTO_LIST 
  134. setopt AUTO_MENU 
  135. #开启此选项,补全时会直接选中菜单项 
  136. #setopt MENU_COMPLETE 
  137.   
  138. autoload -U compinit 
  139. compinit 
  140.   
  141. #自动补全缓存 
  142. #zstyle ':completion::complete:*' use-cache on 
  143. #zstyle ':completion::complete:*' cache-path .zcache 
  144. #zstyle ':completion:*:cd:*' ignore-parents parent pwd 
  145.   
  146. #自动补全选项 
  147. zstyle ':completion:*' verbose yes 
  148. zstyle ':completion:*' menu select 
  149. zstyle ':completion:*:*:default' force-list always 
  150. zstyle ':completion:*' select-prompt '%SSelect:  lines: %L  matches: %M  [%p]' 
  151.   
  152. zstyle ':completion:*:match:*' original only 
  153. zstyle ':completion::prefix-1:*' completer _complete 
  154. zstyle ':completion:predict:*' completer _complete 
  155. zstyle ':completion:incremental:*' completer _complete _correct 
  156. zstyle ':completion:*' completer _complete _prefix _correct _prefix _match _approximate 
  157.   
  158. #路径补全 
  159. zstyle ':completion:*' expand 'yes' 
  160. zstyle ':completion:*' squeeze-shlashes 'yes' 
  161. zstyle ':completion::complete:*' '\\' 
  162.   
  163. #彩色补全菜单 
  164. eval $(dircolors -b) 
  165. export ZLSCOLORS="${LS_COLORS}" 
  166. zmodload zsh/complist 
  167. zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS} 
  168. zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31' 
  169.   
  170. #修正大小写 
  171. zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}' 
  172. #错误校正 
  173. zstyle ':completion:*' completer _complete _match _approximate 
  174. zstyle ':completion:*:match:*' original only 
  175. zstyle ':completion:*:approximate:*' max-errors 1 numeric 
  176.   
  177. #kill 命令补全 
  178. compdef pkill=kill 
  179. compdef pkill=killall 
  180. zstyle ':completion:*:*:kill:*' menu yes select 
  181. zstyle ':completion:*:*:*:*:processes' force-list always 
  182. zstyle ':completion:*:processes' command 'ps -au$USER' 
  183.   
  184. #补全类型提示分组 
  185. zstyle ':completion:*:matches' group 'yes' 
  186. zstyle ':completion:*' group-name '' 
  187. zstyle ':completion:*:options' description 'yes' 
  188. zstyle ':completion:*:options' auto-description '%d' 
  189. zstyle ':completion:*:descriptions' format $'\e[01;33m -- %d --\e[0m' 
  190. zstyle ':completion:*:messages' format $'\e[01;35m -- %d --\e[0m' 
  191. zstyle ':completion:*:warnings' format $'\e[01;31m -- No Matches Found --\e[0m' 
  192. zstyle ':completion:*:corrections' format $'\e[01;32m -- %d (errors: %e) --\e[0m' 
  193.   
  194. # cd ~ 补全顺序 
  195. zstyle ':completion:*:-tilde-:*' group-order 'named-directories' 'path-directories' 'users' 'expand' 
  196. #}}} 
  197.   
  198. ##行编辑高亮模式 {{{ 
  199. # Ctrl+@ 设置标记,标记和光标点之间为 region 
  200. zle_highlight=(region:bg=magenta #选中区域 
  201. special:bold      #特殊字符 
  202. isearch:underline)#搜索时使用的关键字 
  203. #}}} 
  204.   
  205. ##空行(光标在行首)补全 "cd " {{{ 
  206. user-complete(){ 
  207. case $BUFFER in 
  208. "" )                       # 空行填入 "cd " 
  209. BUFFER="cd " 
  210. zle end-of-line 
  211. zle expand-or-complete 
  212. ;; 
  213. "cd --" )                  # "cd --" 替换为 "cd +" 
  214. BUFFER="cd +" 
  215. zle end-of-line 
  216. zle expand-or-complete 
  217. ;; 
  218. "cd +-" )                  # "cd +-" 替换为 "cd -" 
  219. BUFFER="cd -" 
  220. zle end-of-line 
  221. zle expand-or-complete 
  222. ;; 
  223. * ) 
  224. zle expand-or-complete 
  225. ;; 
  226. esac 
  227. zle -N user-complete 
  228. bindkey "\t" user-complete 
  229. #}}} 
  230.   
  231. ##在命令前插入 sudo {{{ 
  232. #定义功能 
  233. sudo-command-line() { 
  234. [[ -z $BUFFER ]] && zle up-history 
  235. [[ $BUFFER != sudo\ * ]] && BUFFER="sudo $BUFFER" 
  236. zle end-of-line                 #光标移动到行末 
  237. zle -N sudo-command-line 
  238. #定义快捷键为: [Esc] [Esc] 
  239. bindkey "\e\e" sudo-command-line 
  240. #}}} 
  241.   
  242. #命令别名 {{{ 
  243. alias cp='cp -i' 
  244. alias mv='mv -i' 
  245. alias rm='rm -i' 
  246. alias ls='ls -F --color=auto' 
  247. alias ll='ls -al' 
  248. alias grep='grep --color=auto' 
  249. alias la='ls -a' 
  250. alias pacman='sudo pacman-color' 
  251. alias p='sudo pacman-color' 
  252. alias y='yaourt' 
  253. alias h='htop' 
  254. alias vim='sudo vim' 
  255.   
  256. #[Esc][h] man 当前命令时,显示简短说明 
  257. alias run-help >&/dev/null && unalias run-help 
  258. autoload run-help 
  259.   
  260. #历史命令 top10 
  261. alias top10='print -l  ${(o)history%% *} | uniq -c | sort -nr | head -n 10' 
  262. #}}} 
  263.   
  264. #路径别名 {{{ 
  265. #进入相应的路径时只要 cd ~xxx 
  266. hash -d A="/media/ayu/dearest" 
  267. hash -d H="/media/data/backup/ayu" 
  268. hash -d E="/etc/" 
  269. hash -d D="/home/ayumi/Documents" 
  270. #}}} 
  271.   
  272. ##for Emacs {{{ 
  273. #在 Emacs终端 中使用 Zsh 的一些设置 不推荐在 Emacs 中使用它 
  274. #if [[ "$TERM" == "dumb" ]]; then 
  275. #setopt No_zle 
  276. #PROMPT='%n@%M %/ 
  277. #>>' 
  278. #alias ls='ls -F' 
  279. #fi 
  280. #}}} 
  281.   
  282. #{{{自定义补全 
  283. #补全 ping 
  284. zstyle ':completion:*:ping:*' hosts 192.168.1.{1,50,51,100,101} www.google.com 
  285.   
  286. #补全 ssh scp sftp 等 
  287. #zstyle -e ':completion::*:*:*:hosts' hosts 'reply=(${=${${(f)"$(cat {/etc/ssh_,~/.ssh/known_}hosts(|2)(N) /dev/null)"}%%[# ]*}//,/ })' 
  288. #}}} 
  289.   
  290. #{{{ F1 计算器 
  291. arith-eval-echo() { 
  292. LBUFFER="${LBUFFER}echo \$(( " 
  293. RBUFFER=" ))$RBUFFER" 
  294. zle -N arith-eval-echo 
  295. bindkey "^[[11~" arith-eval-echo 
  296. #}}} 
  297.   
  298. ####{{{ 
  299. function timeconv { date -d @$1 +"%Y-%m-%d %T" } 
  300.   
  301. # }}} 
  302.   
  303. zmodload zsh/mathfunc 
  304. autoload -U zsh-mime-setup 
  305. zsh-mime-setup 
  306. setopt EXTENDED_GLOB 
  307. #autoload -U promptinit 
  308. #promptinit 
  309. #prompt redhat 
  310.   
  311. setopt correctall 
  312. autoload compinstall 
  313.   
  314. #漂亮又实用的命令高亮界面 
  315. setopt extended_glob 
  316. TOKENS_FOLLOWED_BY_COMMANDS=('|' '||' ';' '&' '&&' 'sudo' 'do' 'time' 'strace') 
  317.   
  318. recolor-cmd() { 
  319.      region_highlight=() 
  320.      colorize=true 
  321.      start_pos=0 
  322.      for arg in ${(z)BUFFER}; do 
  323.          ((start_pos+=${#BUFFER[$start_pos+1,-1]}-${#${BUFFER[$start_pos+1,-1]## #}})) 
  324.          ((end_pos=$start_pos+${#arg})) 
  325.          if $colorize; then 
  326.              colorize=false 
  327.              res=$(LC_ALL=C builtin type $arg 2>/dev/null) 
  328.              case $res in 
  329.                  *'reserved word'*)   style="fg=magenta,bold";; 
  330.                  *'alias for'*)       style="fg=cyan,bold";; 
  331.                  *'shell builtin'*)   style="fg=yellow,bold";; 
  332.                  *'shell function'*)  style='fg=green,bold';; 
  333.                  *"$arg is"*) 
  334.                      [[ $arg = 'sudo' ]] && style="fg=red,bold" || style="fg=blue,bold";; 
  335.                  *)                   style='none,bold';; 
  336.              esac 
  337.              region_highlight+=("$start_pos $end_pos $style") 
  338.          fi 
  339.          [[ ${${TOKENS_FOLLOWED_BY_COMMANDS[(r)${arg//|/\|}]}:+yes} = 'yes' ]] && colorize=true 
  340.          start_pos=$end_pos 
  341.      done 
  342. check-cmd-self-insert() { zle .self-insert && recolor-cmd } 
  343. check-cmd-backward-delete-char() { zle .backward-delete-char && recolor-cmd } 
  344.   
  345. zle -N self-insert check-cmd-self-insert 
  346. zle -N backward-delete-char check-cmd-backward-delete-char  
  1. # man page highlight 
  2. export LESS_TERMCAP_mb=$'\E[01;31m'       # begin blinking 
  3. export LESS_TERMCAP_md=$'\E[01;38;5;74m'  # begin bold 
  4. export LESS_TERMCAP_me=$'\E[0m'           # end mode 
  5. export LESS_TERMCAP_se=$'\E[0m'           # end standout-mode 
  6. export LESS_TERMCAP_so=$'\E[38;5;246m'    # begin standout-mode - info box 
  7. export LESS_TERMCAP_ue=$'\E[0m'           # end underline 
  8. export LESS_TERMCAP_us=$'\E[04;38;5;146m' # begin underline 


zsh 的牛粪之处在于不仅可以设置通用别名,还能针对文件类型设置对应的打开程序,比如:

alias -s html=mate,意思就是你在命令行输入 hello.html,zsh会为你自动打开 TextMat 并读取 hello.html; alias -s gz='tar -xzvf',表示自动解压后缀为 gz 的压缩包。

总之,只有想不到,木有做不到。

设置完环境变量和别名之后,基本上就可以用了,如果你是个主题控,还可以玩玩 zsh 的主题。在 .zshrc 里找到ZSH_THEME,就可以设置主题了,默认主题是:

ZSH_THEME=”robbyrussell”

oh my zsh 提供了数十种主题,相关文件在~/.oh-my-zsh/themes目录下,你可以随意选择,也可以编辑主题满足自己的变态需求,我采用了默认主题robbyrussell,不过做了一点小小的改动:

PROMPT='%{$fg_bold[red]%}➜ %{$fg_bold[green]%}%p%{$fg[cyan]%}%d %{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%}% %{$reset_color%}>'
#PROMPT='%{$fg_bold[red]%}➜ %{$fg_bold[green]%}%p %{$fg[cyan]%}%c %{$fg_bold[blue]%}$(git_prompt_info)%{$fg_bold[blue]%} % %{$reset_color%}'

对照原来的版本,我把 c 改为 d,c 表示当前目录,d 表示绝对路径,另外在末尾增加了一个「 > 」,改完之后的效果是这样的:

大家可以尝试进行改造,也算个趣事。

最后我们来说说插件。

插件

oh my zsh 项目提供了完善的插件体系,相关的文件在~/.oh-my-zsh/plugins目录下,默认提供了100多种,大家可以根据自己的实际学习和工作环境采用,想了解每个插件的功能,只要打开相关目录下的 zsh 文件看一下就知道了。插件也是在.zshrc里配置,找到plugins关键字,你就可以加载自己的插件了,系统默认加载 git ,你可以在后面追加内容,如下:

plugins=(git textmate ruby autojump osx mvn gradle)

下面简单介绍几个:

1、git:当你处于一个 git 受控的目录下时,Shell 会明确显示 「git」和 branch,如上图所示,另外对 git 很多命令进行了简化,例如 gco=’git checkout’、gd=’git diff’、gst=’git status’、g=’git’等等,熟练使用可以大大减少 git 的命令长度,命令内容可以参考~/.oh-my-zsh/plugins/git/git.plugin.zsh

2、textmate:mr可以创建 ruby 的框架项目,tm finename 可以用 textmate 打开指定文件。

3、osx:tab 增强,quick-look filename 可以直接预览文件,man-preview grep 可以生成 grep手册 的pdf 版本等。

4、autojump:zsh 和 autojump 的组合形成了 zsh 下最强悍的插件,今天我们主要说说这货。

首先安装autojump,如果你用 Mac,可以使用 brew 安装:

brew install autojump

如果是 Linux,去下载 autojump 的最新版本,比如:

wget https://github.com/downloads/joelthelion/autojump/autojump_v21.1.2.tar.gz

解压缩后进入目录,执行

./install.sh

最后把以下代码加入.zshrc:

[[ -s ~/.autojump/etc/profile.d/autojump.sh ]] && . ~/.autojump/etc/profile.d/autojump.sh

至此,安装、配置、插件三位一体,终极 Shell 全面登场。退出终端会话重新登录,开始感受 zsh 的训疾如风!

使用 zsh

1、兼容 bash,原来使用 bash 的兄弟切换过来毫无压力,该咋用咋用。

2、强大的历史纪录功能,输入 grep 然后用上下箭头可以翻阅你执行的所有 grep 命令。

3、智能拼写纠正,输入gtep mactalk * -R,系统会提示:zsh: correct ‘gtep’ to ‘grep’ [nyae]? 比妹纸贴心吧,她们向来都是让你猜的……

4、各种补全:路径补全、命令补全,命令参数补全,插件内容补全等等。触发补全只需要按一下或两下 tab 键,补全项可以使用 ctrl+n/p/f/b上下左右切换。比如你想杀掉 Java 的进程,只需要输入 kill java + tab键,如果只有一个 java 进程,zsh 会自动替换为进程的 pid,如果有多个则会出现选择项供你选择。ssh + 空格 + 两个tab键,zsh会列出所有访问过的主机和用户名进行补全

5、智能跳转,安装了autojump之后,zsh 会自动记录你访问过的目录,通过 j + 目录名 可以直接进行目录跳转,而且目录名支持模糊匹配和自动补全,例如你访问过Hadoop-1.0.0目录,输入j hado 即可正确跳转。j –stat 可以看你的历史路径库。

6、目录浏览和跳转:输入 d,即可列出你在这个会话里访问的目录列表,输入列表前的序号,即可直接跳转。

7、在当前目录下输入 .. 或 … ,或直接输入当前目录名都可以跳转,你甚至不再需要输入 cd 命令了。

8、通配符搜索:ls -l **/*.sh,可以递归显示当前目录下的 shell 文件,文件少时可以代替 find,文件太多就歇菜了。

9、更强的别名:请参考配置一节。

10、插件支持:请参考插件一节。

posted @ 2016-05-21 09:16  追鑫少年  阅读(2610)  评论(0编辑  收藏  举报