Chinaunix首页 | 论坛 | 博客
  • 博客访问: 499608
  • 博文数量: 401
  • 博客积分: 244
  • 博客等级: 入伍新兵
  • 技术积分: 2215
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-04 10:02
文章分类

全部博文(401)

文章存档

2013年(37)

2012年(364)

分类:

2012-12-17 10:12:02

原文地址:终极Shell——Zsh 作者:skysong1982

有句话这样说,zsh: The last shell you’ll ever need! Z是最后一个字母,所以是终极Shell。

    我曾经搜索到一个比较各种Shell的文章,Zsh交互性是A+级别的,远高于其它Shell。在编程方面,Zsh是A级的吧,也是最高的。只是不知道出于什么原因,Zsh被严重的低估了。

    大多数的Linux用户比较偏爱Bash,因为大多数的发行版默认的就是它。凭心而论,Bash确实比Csh之流的好用多了。不过Bash也有很多地方不尽人意,像自动补全的功能不够强大,定位较长路径不够方便等。

    后来我使用Zsh。如果不调整一些必要的配置的话,Zsh甚至还不如Bash好用。这也是很多人尝试过并放弃过的原因。

    不熟悉Zsh的人,对Zsh最深刻的印象应该就是它的命令提示符了。它支持右侧对齐的提示符,并且可以配置成这个样子的:

    不过我还是喜欢比较简单的样式。

    Zsh的自动补全功能十分的强大,如图所示:

    它可以自动补全命令、参数、文件名、进程、用户名、变量、权限符等。

    Zsh还有一个贴心的功能:路径别名。假设有一个很长的路径,例如/home/lighttpd/html,可以把这个路径命名为 ~WWW。

    Zsh可以使用Emacs风格的键绑定,习惯Bash键绑定的朋友无需重新适应。Zsh兼容大多数主流Shell,像Bash、Csh等。

下面讲解一下Zsh配置文件:

    #命令提示符 ( ^[ 是一个特殊字符 在vi插入模式下 按Ctrl+v ESC 插入该字符)
    PROMPT='%{ ^[[36m%}%n%{^[[35m%}@%{^[[34m%}%M %{^[[33m%}%D %T %{^[[32m%}%/
    %{^[[31m%}>>%{^[[m%}'

    #关于历史纪录的配置
    # number of lines kept in history
    export HISTSIZE=10000
    # # number of lines saved in the history after logout
    export SAVEHIST=10000
    # # location of history
    export HISTFILE=~/.zhistory
    # # append command to history file once executed
    setopt INC_APPEND_HISTORY

    #Disable core dumps
    limit coredumpsize 0

    #Emacs风格键绑定
    bindkey -e
    #设置DEL键为向后删除
    bindkey "\e[3~" delete-char

    #以下字符视为单词的一部分
    WORDCHARS='*?_-[]~=&;!#$%^(){}<>'

    #自动补全功能
    setopt AUTO_LIST
    setopt AUTO_MENU
    setopt MENU_COMPLETE

    autoload -U compinit
    compinit

    # Completion caching
    zstyle ':completion::complete:*' use-cache on
    zstyle ':completion::complete:*' cache-path .zcache
    #zstyle ':completion:*:cd:*' ignore-parents parent pwd

    #Completion Options
    zstyle ':completion:*:match:*' original only
    zstyle ':completion::prefix-1:*' completer _complete
    zstyle ':completion:predict:*' completer _complete
    zstyle ':completion:incremental:*' completer _complete _correct
    zstyle ':completion:*' completer _complete _prefix _correct _prefix _match _approximate

    # Path Expansion
    zstyle ':completion:*' expand 'yes'
    zstyle ':completion:*' squeeze-shlashes 'yes'
    zstyle ':completion::complete:*' '\\'

    zstyle ':completion:*:*:*:default' menu yes select
    zstyle ':completion:*:*:default' force-list always

    # GNU Colors 需要/etc/DIR_COLORS文件 否则自动补全时候选菜单中的选项不能彩色显示
    [ -f /etc/DIR_COLORS ] && eval $(dircolors -b /etc/DIR_COLORS)
    export ZLSCOLORS="${LS_COLORS}"
    zmodload zsh/complist
    zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
    zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)*=0=01;31'

    zstyle ':completion:*' completer _complete _match _approximate
    zstyle ':completion:*:match:*' original only
    zstyle ':completion:*:approximate:*' max-errors 1 numeric

    compdef pkill=kill
    compdef pkill=killall
    zstyle ':completion:*:*:kill:*' menu yes select
    zstyle ':completion:*:processes' command 'ps -au$USER'

    # Group matches and Describe
    zstyle ':completion:*:matches' group 'yes'
    zstyle ':completion:*:options' description 'yes'
    zstyle ':completion:*:options' auto-description '%d'
    zstyle ':completion:*:descriptions' format $'\e[01;33m -- %d --\e[0m'
    zstyle ':completion:*:messages' format $'\e[01;35m -- %d --\e[0m'
    zstyle ':completion:*:warnings' format $'\e[01;31m -- No Matches Found --\e[0m'

    #命令别名
    alias cp='cp -i'
    alias mv='mv -i'
    alias rm='rm -i'
    alias ls='ls -F --color=auto'
    alias ll='ls -l'
    alias grep='grep --color=auto'
    alias ee='emacsclient -t'

    #路径别名 进入相应的路径时只要 cd ~xxx
    hash -d WWW="/home/lighttpd/html"
    hash -d ARCH="/mnt/arch"
    hash -d PKG="/var/cache/pacman/pkg"
    hash -d E="/etc/env.d"
    hash -d C="/etc/conf.d"
    hash -d I="/etc/rc.d"
    hash -d X="/etc/X11"
    hash -d BK="/home/r00t/config_bak"

    ##for Emacs在Emacs终端中使用Zsh的一些设置 不推荐在Emacs中使用它
    if [[ "$TERM" == "dumb" ]]; then
    setopt No_zle
    %/
    >>'
    alias ls='ls -F'
    fi

    效果超炫的提示符:

    #效果超炫的提示符

    function precmd {

    local TERMWIDTH
    (( TERMWIDTH = ${COLUMNS} - 1 ))

    ###
    # Truncate the path if it's too long.

    PR_FILLBAR=""
    PR_PWDLEN=""

    local promptsize=${#${(%):---()---()--}}
    local pwdsize=${#${(%):-%~}}

    if [[ "$promptsize + $pwdsize" -gt $TERMWIDTH ]]; then
    ((PR_PWDLEN=$TERMWIDTH - $promptsize))
    else
    PR_FILLBAR="\${(l.(($TERMWIDTH - ($promptsize + $pwdsize)))..${PR_HBAR}.)}"
    fi

    ###
    # Get APM info.

    #if which ibam > /dev/null; then
    #PR_APM_RESULT=`ibam --percentbattery`
    #elif which apm > /dev/null; then
    #PR_APM_RESULT=`apm`
    #fi
    }

    setopt extended_glob
    preexec () {
    if [[ "$TERM" == "screen" ]]; then
    local CMD=${1[(wr)^(*=*|sudo|-*)]}
    echo -n "\ek$CMD\e\\"
    fi
    }

    setprompt () {
    ###
    # Need this so the prompt will work.

    setopt prompt_subst

    ###
    # See if we can use colors.

    autoload colors zsh/terminfo
    if [[ "$terminfo[colors]" -ge 8 ]]; then
    colors
    fi
    for color in RED GREEN YELLOW BLUE MAGENTA CYAN WHITE; do
    eval PR_$color='%{$terminfo[bold]$fg[${(L)color}]%}'
    eval PR_LIGHT_$color='%{$fg[${(L)color}]%}'
    (( count = $count + 1 ))
    done
    PR_NO_COLOUR="%{$terminfo[sgr0]%}"

    ###
    # See if we can use extended characters to look nicer.

    typeset -A altchar
    set -A altchar ${(s..)terminfo[acsc]}
    PR_SET_CHARSET="%{$terminfo[enacs]%}"
    PR_SHIFT_IN="%{$terminfo[smacs]%}"
    PR_SHIFT_OUT="%{$terminfo[rmacs]%}"
    PR_HBAR=${altchar[q]:--}
    #PR_HBAR=" "
    PR_ULCORNER=${altchar[l]:--}
    PR_LLCORNER=${altchar[m]:--}
    PR_LRCORNER=${altchar[j]:--}
    PR_URCORNER=${altchar[k]:--}

    ###
    # Decide if we need to set titlebar text.

    case $TERM in
    xterm*)
    PR_TITLEBAR=$'%{\e]0;%(!.-=*[ROOT]*=- | .)%n@%m:%~ | ${COLUMNS}x${LINES} | %y\a%}'
    ;;
    screen)
    PR_TITLEBAR=$'%{\e_screen \005 (\005t) | %(!.-=[ROOT]=- | .)%n@%m:%~ | ${COLUMNS}x${LINES} | %y\e\\%}'
    ;;
    *)
    PR_TITLEBAR=''
    ;;
    esac

    ###
    # Decide whether to set a screen title
    if [[ "$TERM" == "screen" ]]; then
    PR_STITLE=$'%{\ekzsh\e\\%}'
    else
    PR_STITLE=''
    fi

    ###
    # APM detection

    #if which ibam > /dev/null; then
    #PR_APM='$PR_RED${${PR_APM_RESULT[(f)1]}[(w)-2]}%%(${${PR_APM_RESULT[(f)3]}[(w)-1]})$PR_LIGHT_BLUE:'
    #elif which apm > /dev/null; then
    #PR_APM='$PR_RED${PR_APM_RESULT[(w)5,(w)6]/\% /%%}$PR_LIGHT_BLUE:'
    #else
    PR_APM=''
    #fi

    ###
    # Finally, the prompt.

    PROMPT='$PR_SET_CHARSET$PR_STITLE${(e)PR_TITLEBAR}\
    $PR_CYAN$PR_SHIFT_IN$PR_ULCORNER$PR_BLUE$PR_HBAR$PR_SHIFT_OUT(\
    $PR_GREEN%(!.%SROOT%s.%n)$PR_GREEN@%m:%l\
    $PR_BLUE)$PR_SHIFT_IN$PR_HBAR$PR_CYAN$PR_HBAR${(e)PR_FILLBAR}$PR_BLUE$PR_HBAR$PR_SHIFT_OUT(\
    $PR_MAGENTA%$PR_PWDLEN<...<%~%<<\
    $PR_BLUE)$PR_SHIFT_IN$PR_HBAR$PR_CYAN$PR_URCORNER$PR_SHIFT_OUT\

    $PR_CYAN$PR_SHIFT_IN$PR_LLCORNER$PR_BLUE$PR_HBAR$PR_SHIFT_OUT(\
    %(?..$PR_LIGHT_RED%?$PR_BLUE:)\
    ${(e)PR_APM}$PR_YELLOW%D{%H:%M}\
    $PR_LIGHT_BLUE:%(!.$PR_RED.$PR_WHITE)%#$PR_BLUE)$PR_SHIFT_IN$PR_HBAR$PR_SHIFT_OUT\
    $PR_CYAN$PR_SHIFT_IN$PR_HBAR$PR_SHIFT_OUT\
    $PR_NO_COLOUR '

    RPROMPT=' $PR_CYAN$PR_SHIFT_IN$PR_HBAR$PR_BLUE$PR_HBAR$PR_SHIFT_OUT\
    ($PR_YELLOW%D{%a,%b%d}$PR_BLUE)$PR_SHIFT_IN$PR_HBAR$PR_CYAN$PR_LRCORNER$PR_SHIFT_OUT$PR_NO_COLOUR'

    PS2='$PR_CYAN$PR_SHIFT_IN$PR_HBAR$PR_SHIFT_OUT\
    $PR_BLUE$PR_SHIFT_IN$PR_HBAR$PR_SHIFT_OUT(\
    $PR_LIGHT_GREEN%_$PR_BLUE)$PR_SHIFT_IN$PR_HBAR$PR_SHIFT_OUT\
    $PR_CYAN$PR_SHIFT_IN$PR_HBAR$PR_SHIFT_OUT$PR_NO_COLOUR '
    }

    setprompt

阅读(503) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~