bash用久了,有些地方开始觉得不爽,于是想看看有没有更好的选择。原来在网上瞎逛时,已经很多次看到有人推荐zsh了,加上zsh高度兼容bash,于是就来折腾这个。
不过试验了一下oh-my-zsh,感觉功能太强大了,太多东西不知道怎么配置的,这种过于“不知其所以然”的感觉我不太喜欢。于是自己来折腾,觉得基本够自己用就行了。

1. 补全

很多介绍zsh的文章都说zsh相对bash的一个优点是支持命令选项和参数的补全


(这两幅图来自 Z使用 Zsh 的九个理由 - 博客 - 伯乐在线)

其实bash里面如果你安装了bash-completion这个包的话,很多命令(比如pkill, dpkg, git等等,我的机器上/etc/bash_completion.d/下面有200多个命令的补全配置。注意/etc/bash_completion.d/git其实是git包提供的,而/etc/bash_completion.d/mercurial其实是mercurial包提供的) 。

不过zsh在补全还是有些比bash强的地方,尤其是涉及到交互的地方:

  1. 按TAB补全时,能够在多个备选项之间循环,如果备选项不多的话,你只需要不断按TAB就行了,而bash只会列出备选项,你得多输入一个或几个字母直到备选项缩小到一个了它才真正给你补全;
  2. 有一定的容错能力: 可以在配置文件中添加一句 zstyle ':completion::approximate:' max-errors 1 numeric ,以后输入cd /etc/x11, 按TAB后zsh会给你纠正为/etc/X11 (此条来自 终极Shell——Zsh — LinuxTOY,那里有详细的说明);
  3. 补全时可以用光标键或者Ctrl-p/Ctrl-n来挑选被选项(即很多文章说到的menu
    select方式)。不过针对第这一点,就得说到zsh的两个缺点:配置太TMD复杂、说明文档也巨罗嗦,你要是对缺省配置有一点点不满意,或者搞错了,
    就很容易陷入泥沼里,有兴趣的自己研究这个文档吧: Chapter 6: Completion, old and new - A User's Guide to the Z-Shell (P.S. 一篇简单的介绍: Refining Linux: ZSH Gem #5: Menu selection )

另外,zsh自带的补全源的确比bash-completion多,我这里find /usr/share/zsh/functions/Completion -type f | wc -l 的结果是688个文件(参见 Debian -- Filelist of package zsh-common/jessie/all )

2. 在目录中穿梭(cd命令)

在写代码过程中,会在各个目录之间来回切换,原来用bash时有两点最不爽:

  • 对cd命令有TAB补全的功能,但每一级目录都需要按TAB(并且有多个备选项的话需要继续输入才行)还是觉得繁琐,觉得效率不高;
  • pushd/popd/dirs虽然很有用,但很多时候等你想回到过去的某个目录时,才发现当时忘记pushd了

2.1 zsh的改进方法

  • 首先,假如/opt/rubystack-1.9/下面有apache2apps这两个目录,输入cd /opt/rubystack-1.9/a然后按TAB的话,首先会补齐为apache2,再按TAB会补齐为apps,不需要象bash下面那样继续输入字母;
  • 如果你想进入/opt/rubystack-1.9/apps/redmine,那么可以先这样输入 cd /o/r/a/r 然后按TAB,如果这是唯一匹配,那么zsh会补全为/opt/rubystack-1.9/apps/redmine,但如果还存在一个/opt/rubystack-1.8/apps/redmine,那zsh就会列出来让你挑选;
  • 如果你现在在/opt/rubystack-1.9/apps/redmine,但你想进入/opt/rubystack-1.8/apps/redmine,可以这样: cd 1.9 1.8 这表示将完整路径上的1.9替换为1.8再使用;
  • 你可以打开auto_pushd选项(通过命令setopt auto_pushd),这样你通过cd切换目录时,zsh会自动将前一个目录加到栈里,这样你就不会因为忘记pushd而遗憾了;
  • bash里面可以cd -回到上一个目录(即最后一次调用cd时所在的目录),但zsh里面有cd
    -2, cd +3这样的用法,并且在输入cd
    -之后按TAB能够列出目录名供挑选补全。不过需要注意的是,这里-2并不表示倒数第二次调用cd时的目录,而是倒数第二次通过pushd记录的目录,如
    果打开了auto_pushd选项,那么这两个的含义倒是一样的;
  • zsh里面将~这个符号的用法进行了扩展,我们可以用hash -d www=/var/www/html定义一个路径别名,然后用cd ~www就可以进入到/var/www/html

参考资料: Refining Linux: ZSH Gem #20: Changing directories the pro's way

2.2 autojump: 快速进入频繁访问的目录(bash/zsh通用)

使用方法

  1. 下载这个 https://github.com/rupa/z/blob/master/z.sh (这个文件名跟zsh没有必然联系),放到某个位置(比如/usr/local/lib/z.sh);
  2. ~/.bashrc或者~/.zshrc里面加入一句source /usr/local/lib/z.sh,这使得以后的cd命令会被z.sh统计各目录访问频率;
  3. 你得按老方法切换目录一阵,以便z.sh能够知道哪些目录是最常用的;
  4. z -l命令即可列出历史上你访问各个目录的频率了;
  5. z regex 命令即可进入你频繁访问的目录

3. 提示符设置

oh-my-zsh提供了很多很花哨且功能强大的提示符设置,比如显示git当前分支名、提交状态等等:

3.1 基本设置

不过我觉得Debian缺省推荐的(见/etc/zsh/newuser.zshrc.recommended )提示符设置就可以了(只是简单地显示用户名、机器名和全路径)

autoload -Uz promptinit
promptinit
prompt adam1

3.2 RPROMPT

不过我有时也想显示一点别的内容,zsh有个RPROMPT环境变量用来设置显示在右边的提示符,可以在有需要的时候即设即用,很方便。比如我用它配置了 用来显示当前git仓库名、分支名和提交状态(也许你又要问我为什么不用oh-my-zsh,那是因为我没看见它显示git仓库名,而这个庞大的东西我不 知道怎么去修改它。甚至下面这段代码我也是抛弃了StackOverflow上得票最多的答案,而是选了个得分为0的答案为基础,仅仅因为后面这个我能看懂,能修改它)

_git_repo_name() {
gittopdir=$(git rev-parse --git-dir 2> /dev/null)
if [[ "foo$gittopdir" == "foo.git" ]]; then
echo `basename $(pwd)`
elif [[ "foo$gittopdir" != "foo" ]]; then
echo `dirname $gittopdir | xargs basename`
fi
}
_git_branch_name() {
git branch 2>/dev/null | awk '/^\*/ { print $2 }'
}
_git_is_dirty() {
git diff --quiet 2> /dev/null || echo '*'
} setopt prompt_subst
RPROMPT='$(_git_repo_name) $(_git_branch_name) $(_git_is_dirty)'

4. 命令历史

4.1 多会话共享历史

我一般会用tmux开多个会话,这种情况下记得刚才输入过这个命令,但找了半天没找到才意识到好像是在另外一个window/pane里面输入的。zsh的一个功能特性是share_history,这样在一个会话里面可以访问另外一个会话的历史命令了。不过这个特性可能会让人有些不习惯,这样的话可以试试另外两个选项:setopt APPEND_HISTORY或者setopt INC_APPEND_HISTORY.

参考资料: Refining Linux: ZSH Gem #15: Shared history

4.2 a clear history

setopt hist_ignore_space
alias cd=" cd"
alias ls=" ls"

第一句使得不将以空格开始的命令行记录到历史当中(这在需要在i命令行中明文输入密码时也挺有用,这样不会在历史记录中看到你的密码了);
后面两句使得cd/ls这些简单的命令就不记录到历史了,这样用history查看的时候是不是更清晰了?

来自 : http://chneukirchen.org/blog/archive/2012/02/10-new-zsh-tricks-you-may-not-know.html

另一个技巧: 每个目录记录自己的history: <http://linuxtoy.org/archives/zsh_per_dir_hist.html>

http://www.lowlevelmanager.com/2012/05/zsh-history-expansion.html

5. 其它设置

5.1 通配符带子目录

zsh支持更复杂的文件名匹配,不过我大部分我都没去学,只记住了我认为最有用的一个:

grep ":project_menu" **/*.erb

这个**会搜索所有的子目录,也就避免了用find了(bash下就得借用find了: find . -name '*.erb | xargs grep ":project_menu")

5.2 setopt no_nomatch

这是zsh缺省跟bash不兼容的一个地方。在zsh下,如果你执行dpkg -l firefox*,很可能zsh不会列出名字以firefox开头的包,而是告诉你zsh: no matches found: firefox*。这是因为zsh缺省情况下始终自己解释这个firefox*,而不会传递给dpkg来解释。

解决这个问题的方法是在~/.zshrc中加入:

setopt no_nomatch

5.3 ~/.inputrc无法工作?

zsh没有使用libreadline,而是自己实现了一套类似的(名字叫做zle - zsh command line
editor)。所以你原来在~/.inputrc里面配置的快捷键都不再有效,而是要用zle的语法重新配置一遍(也在~/.zshrc中配置)。

例子1:

bindkey "^[0H" beginning-of-line
bindkey "^[OF" end-of-line

例子2:

#按下F5时自动输入z -l | tail\n
bindkey -s "\e[15~" "z -l | tail\n"

5.4 让M-backspace象bash那样只回删一个单词

这是zsh跟bash不兼容的另一个地方,M-backspace会回删整个参数,而不是像bash/emacs那样只删除一个单词。

解决方法是在~/.zshrc中加入:

autoload -U select-word-style
select-word-style bash

(来自: http://stackoverflow.com/a/1438523 )

6. 参考资料

- [系统管理员工具包: 充分利用 zsh](http://www.ibm.com/developerworks/cn/aix/library/au-satzsh.html)
- [幕启:介绍 Z shell](http://www.ibm.com/developerworks/cn/linux/shell/z/)
- [终极Shell——Zsh — LinuxTOY](http://linuxtoy.org/archives/zsh.html)
- [使用 Zsh 的九个理由 - 博客 - 伯乐在线](http://blog.jobbole.com/28829/)

我的zsh简单设置的更多相关文章

  1. 【配置】检测到在集成的托管管道模式下不适用的ASP.NET设置的解决方法(非简单设置为【经典】模式)。

      ×   检测到在集成的托管管道模式下不适用的ASP.NET设置的解决方法(非简单设置为[经典]模式). 我们将ASP.NET程序从IIS6移植到IIS7,可能运行提示以下错误: HTTP 错误 5 ...

  2. EditPlus开发Python的简单设置

    EditPlus是一个功能强大的编辑器,这里介绍用它来开发Python程序所需要的简单设置. 环境:win7 1.设置Python语法缩进: [1]工具-->设置用户自定义工具 [2]在分类面板 ...

  3. Android课程---Android Studio简单设置

    Android Studio 简单设置 界面设置 默认的 Android Studio 为灰色界面,可以选择使用炫酷的黑色界面.Settings-->Appearance-->Theme, ...

  4. Kali-linux安装之后的简单设置

    1.更新软件源:修改sources.list文件:leafpad /etc/apt/sources.list然后选择添加以下适合自己较快的源(可自由选择,不一定要全部): #官方源deb http:/ ...

  5. 【转】Android Studio简单设置

    原文网址:http://ask.android-studio.org/?/article/14 Android Studio 简单设置 界面设置 默认的 Android Studio 为灰色界面,可以 ...

  6. Android Studio简单设置(转)

    Android Studio 简单设置 界面设置 默认的 Android Studio 为灰色界面,可以选择使用炫酷的黑色界面.Settings --> Appearance --> Th ...

  7. IIS 7.5 使用URL Rewrite模块简单设置网页跳转

    原文 IIS 7.5 使用URL Rewrite模块简单设置网页跳转 我们都知道Apache可以在配置文件里方便的设置针对网页或网站的rewrite,但是最近接手了一组IIS服务器,发现这货简单的没有 ...

  8. mysql加速导入数据的简单设置

    mysql加速导入数据的简单设置 # 修改前查询参数值 show variables like 'foreign_key_checks'; show variables like 'unique_ch ...

  9. 在linux上安装MySQL数据库,并简单设置用户密码,登录MySQL

    在新装的Centos系统上安装MySQL数据库. <p><a href="http://www.cnblogs.com/tijun/">提君博客原创< ...

随机推荐

  1. 【Spring】SpringMVC之REST编程风格

    REST架构是一个抽象的概念,目前主要是基于HTTP协议实现,其目的是为了提高系统的可伸缩性.降低应用之间的耦合度.便于架构分布式处理程序.当使用多种语言进行开发的时候,每一种语言对URL的处理不同, ...

  2. Swift 表达式

    前言 Swift 语言使用表达式来表示程序中的最小单位,通常一个表达式是由数字.字符.运算符.变量.常量.函数调用等可以求得值的有意义的排列组成的组合. 根据组合方式的不同,表达式可以分为基本表达式. ...

  3. 【struts2】<package>的配置

    <package>元素可以把逻辑上相关的一组Action.Result.Intercepter等元素封装起来,形成一个独立的模块,package可以继承其他的package,也可以作为父包 ...

  4. python ---Pandas时间序列:生成指定范围的日期

    引入包 import pandas as pd import numpy as np 1.生成指定范围的日期 print pd.date_range('11/1/2018','11/9/2018') ...

  5. javascript some()函数用法详解

    参数说明callback: 要对每个数组元素执行的回调函数.thisObject : 在执行回调函数时定义的this对象. 功能说明对数组中的每个元素都执行一次指定的函数(callback),直到此函 ...

  6. Python 文件 writelines() 方法

    概述 Python 文件 writelines() 方法用于向文件中写入一序列的字符串. 这一序列字符串可以是由迭代对象产生的,如一个字符串列表. 换行需要制定换行符 \n. 语法 writeline ...

  7. 直接获取摄像头传回的图像数据(人脸、微笑、眨眼: 识别--&gt;第一步):图像识别第一步

    转:ios通过摄像头获取特定数据(http://www.2cto.com/kf/201404/290777.html) 凝视: 因为近期项目需求,须要一个可以实现对摄像头图片获取当中部分内容的功能,类 ...

  8. Android Studio 1.1.0 切换主题和绑定 代码提示 快捷键

    这篇文章用于给刚从eclipse 转用 Android Studio 1.1.0的同学看的. 所以经常会更新的. 至于为什么要转Android Studio 1.1.0呢,就自己想吧.没有人强逼的. ...

  9. jquery 获取URL参数并转码的例子

    通过jquery 获取URL参数并进行转码,个人觉得不错,因为有时不转码就会有乱码的问题.jquery 获取URL参数并转码,首先构造一个含有目标参数的正则表达式对象,匹配目标参数并返回参数值代码: ...

  10. 怎么设置Linux swap分区?方法教程

    如何设置Linux swap分区 看到不少朋友问linux下swap分区的问题,收集到一篇 不错的文章 ,分享下. 什么是Swap?Swap,即交换区,除了安装Linux的时候,有多少人关心过它呢?其 ...