打造一个花里胡哨(功能强大)的shell - Oh My Zsh

1 什么是Shell

相对于内核来说,Shell是Linux/Unix的一个外壳,它负责外界与Linux内核的交互,接收用户或其他应用程序的命令,然后把这些命令转化成内核能理解的语言,传给内核,内核是真正干活的,干完之后再把结果返回用户或应用程序。 简单的说,shell就是那“黑乎乎”的命令行。


2 Shell的分类

Linux/Unix提供了很多种Shell,不同的shell具备不同的功能,shell还决定了脚本中函数的语法,Linux中默认的shell是/bin/bash;

想知道你的系统有几种shell,可以通过以下命令查看:

$ cat /etc/shells

显示如下:

/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/zsh
/usr/bin/tmux

bash这个是目前大多数Linux系统默认使用的shell,全名是BourneAgain Shell,一共有40个命令。包含的功能几乎可以涵盖shell所具有的功能,所以一般的shell脚本都会指定它为执行路径。


3 zsh介绍

zsh 是一款功能强大的 shell 软件,它可以兼容 bash,并且提供了很多高效的改进。它是Linux里最庞大的一种shell,它有84个内部命令,也提供了更为强大的功能:

  • 更好的自动补全
  • 更好的文件名展开
  • 丰富的插件
  • 强大的定制性 但是由于配置过于复杂,一般情况下,我们不会使用该shell,直到「oh my zsh」的出现。

Zsh的一些特性

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

强大的历史纪录功能,在用或者方向上键查找历史命令时,zsh支持限制查找。比如输入ls然后再按方向上键,则只会查找用过的ls命令。而此时使用则会仍然按之前的方式查找,忽略ls。  

多个终端会话共享历史记录。经常有多个窗口,tab,tmux的多个session,panel。这些命令历史不能共享实在是很糟糕的回忆。但是有了zsh之后,这些确实成了回忆了,所有的命令历史都可以共享。  

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

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

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

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

在当前目录下输入 .. 或 … ,或直接输入当前目录名都可以跳转,你甚至不再需要输入cd命令了。  
通配符搜索:ls -l **/*.sh,可以递归显示当前目录下的 shell 文件,文件少时可以代替find,文件太多还是用find。

4 zsh安装

如果你用 Mac,就可以直接看下一节,Mac默认已经安装;
如果你用 Redhat Linux,执行:sudo yum install zsh;
如果你用 Ubuntu Linux,执行:sudo apt-get install zsh;

现在zsh已经安装完成了,需要把系统默认的shell由bash切换为zsh
切换shell至zsh,命令如下:

$ chsh -s /bin/zsh

注意,此处不需要root权限,不需要在前面加sudo
返回结果如下:

Changing shell for root.  
Shell changed.  

按提示所述,shell已经更改为zsh了,现在查看一下系统当前使用的shell;

$ echo $SHELL

如果返回结果如下:

/bin/bash

则还没切换过来,需要重启一下服务器后再登陆

$ sudo reboot

重启过后,使用再次查看当前使用的shell, 返回结果如下

/bin/zsh

则表示, shell已经切换成功了。


5. Oh My Zsh

Oh My Zsh是一款社区驱动的命令行工具,正如它的主页上说的,Oh My Zsh 是一种生活方式。它基于zsh命令行,提供了主题配置,插件机制,已经内置的便捷操作。给我们一种全新的方式使用命令行。

Oh My Zsh只是一个对zsh命令行环境的配置包装框架,但它不提供命令行窗口,更不是一个独立的APP。

5.1 安装

官网推荐安装方式:

使用 curl:

$ sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

使用 wget:

$ sh -c "$(wget https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"

安装过程中输出如下

Cloning Oh My Zsh...  
Cloning into '/root/.oh-my-zsh'...  
remote: Counting objects: 712, done.  
remote: Compressing objects: 100% (584/584), done.  
remote: Total 712 (delta 15), reused 522 (delta 4), pack-reused 0  
Receiving objects: 100% (712/712), 443.58 KiB | 27.00 KiB/s, done.  
Resolving deltas: 100% (15/15), done.  
Checking connectivity... done.  
Looking for an existing zsh config...  
Using the Oh My Zsh template file and adding it to ~/.zshrc  
Copying your current PATH and adding it to the end of ~/.zshrc for you.  
Time to change your default shell to zsh!

                              ....is now installed!

Please look over the ~/.zshrc file to select plugins, themes, and options.  
p.s. Follow us at https://twitter.com/ohmyzsh.  
p.p.s. Get stickers and t-shirts at http://shop.planetargon.com.  

到这里,Oh My Zsh 就安装成功了。

Oh My Zsh目录结构
进入~/.oh-my-zsh目录后,看看该目录的结构

⚡ root@finn # ~ $ ls ~/.oh-my-zsh 
cache  CODE_OF_CONDUCT.md  CONTRIBUTING.md  custom  lib  LICENSE.txt  log  oh-my-zsh.sh  plugins  README.md  templates  themes  tools  

lib 提供了核心功能的脚本库
tools 提供安装、升级等功能的快捷工具
plugins 自带插件的存在放位置
templates 自带模板的存在放位置
themes 自带主题文件的存在放位置
custom 个性化配置目录,自安装的插件和主题可放这里


5.2 配置

zsh的配置文件存在当前用户目录中的.zshrc文件,如果你发现切换了shell之后,以前的配置的环境变量不生效了,可以打开 .zshrc文件,找到:

$ vim ~/.zshrc 

# User configuration
 source ~/.bash_profile

指定配置的环境变量文件,之后运行:

$ source .zshrc

更新oh-my-zsh
设置自动更新oh-my-zsh
默认情况下,当oh-my-zsh有更新时,都会给你提示。如果希望让oh-my-zsh自动更新,在~/.zshrc 中添加下面这句

DISABLE_UPDATE_PROMPT=true  

要手动更新,可以执行

$ upgrade_oh_my_zsh

卸载oh my zsh

# 直接在终端中,运行uninstall_oh_my_zsh既可以卸载。
$ uninstall_oh_my_zsh

5.3 主题

在.zshrc文件中找到主题的配置项

# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/robbyrussell/oh-my-zsh/wiki/Themes
# 加载设置名称的主题
# 如果设置的名称为"random", 则会随机加载一个主题
# 在这种情况下, 如果你想要知道是哪个主题, 可以输入命令
# $ echo $RANDOM_THEME 查看

# 这是我设置的主题 agnoster
ZSH_THEME="agnoster"

这里可以设置主题的名字,那么这些主题的名字从哪里找呢?
进入Oh My Zsh的配置目录中:

$ ls ~/.oh-my-zsh/themes

可以看到内置了许多主题,根据主题文件的名字替换就可以了;

agnoster.zsh-theme       dieter.zsh-theme      fwalch.zsh-theme  
alanpeabody.zsh-theme    dogenpunk.zsh-theme   gallifrey.zsh-theme  
amuse.zsh-theme          dpoggi.zsh-theme      gallois.zsh-theme  
apple.zsh-theme          dracula.zsh-theme     garyblessington.zsh-theme  
arrow.zsh-theme          dstufft.zsh-theme     gentoo.zsh-theme  
aussiegeek.zsh-theme     dst.zsh-theme         geoffgarside.zsh-theme  
avit.zsh-theme           duellj.zsh-theme      gianu.zsh-theme  
awesomepanda.zsh-theme   eastwood.zsh-theme    gnzh.zsh-theme  
bira.zsh-theme           edvardm.zsh-theme     gozilla.zsh-theme  
blinks.zsh-theme         emotty.zsh-theme      half-life.zsh-theme  
bureau.zsh-theme         essembeh.zsh-theme    humza.zsh-theme  
candy-kingdom.zsh-theme  evan.zsh-theme        imajes.zsh-theme  
candy.zsh-theme          fino-time.zsh-theme   intheloop.zsh-theme  
...
...

或者我们将主题设置为随机(random),每次打开命令行窗口,都会随机在默认主题中选择一个,如果遇到你喜欢的主题,可以输入命令查看其名字:

$ echo $ZSH_THEME

如果这些默认主题还不能满足你的需要,我们还可以到这里找到更多的主题

https://github.com/robbyrussell/oh-my-zsh/wiki/Themes  
https://github.com/robbyrussell/oh-my-zsh/wiki/External-themes  
https://github.com/unixorn/awesome-zsh-plugins#themes  

5.4 插件

Oh My Zsh 默认自带了一些默认插件,存放在~/.oh-my-zsh/plugins目录中。我们可以查看这些插件:

$ ls ~/.oh-my-zsh/plugins

adb               cask               dirpersist  
alias-finder      catimg             django  
ansible           celery             dnf  
ant               chruby             dnote  
apache2-macports  chucknorris        docker  
arcanist          cloudapp           docker-compose  
archlinux         cloudfoundry       docker-machine  
...
...

我们打开.zshrc配置文件, 定位到plugins,
可以看到默认只开启了git插件,我们可以将要使用的插件的名字以空格相隔或者换行接在后面就可以了,比如:

$ vim ~/.zshrc

plugins=(  
  git
  osx
  autojump
  systemd
  yum
  common-aliases
  git-flow
  history-substring-search
  node
  npm
  docker
  tmux
  navi
)

如果我们要下载第三方的插件,只需要把插件下载存放到~/.oh-my-zsh/plugins中,然后在上面加上插件的名字即可;

更多插件详情见:

https://github.com/robbyrussell/oh-my-zsh/wiki/Plugins-Overview  
https://github.com/unixorn/awesome-zsh-plugins  

5.4.1 推荐插件

navi - denisidoro

开发者是一位来自巴西的小哥Denis Isidoro。 开发的工具 navi

Linux用户的日常困惑

  • 新命令 用完就忘 ?
  • 一时想不起来命令的单词怎么拼?
  • 命令 文档太多反复百度查?

那么你可以看看这个工具 navi 用于命令行的交互式备忘单工具:
安装了navi后,只要键入一个单词,速查表中相关的命令以及用法注释就会实时显示在下方。找到以后我们想要的命令后,用方向键选中后即可直接运行命名。

确保已配置oh-my-zsh $ ZSH_CUSTOM目录,然后将navi克隆到plugins目录中。

plugins_dir="$ZSH_CUSTOM/plugins"  
mkdir -p "$plugins_dir"  
cd "$plugins_dir"  
git clone https://github.com/denisidoro/navi  

然后,将其添加到oh-my-zsh插件数组以自动启用zsh小部件

$ vim ~/.zshrc

# 如果只有已有配置插件, 请在新行添加
plugins=(  
  docker 
  tmux 
  fzf 
  navi
)

最后,重新加载您的zshrc或生成一个新终端以加载navi。完成此操作后,无需进行其他设置,您应该可以将其用作外壳程序小部件。

$ source ~/.zshrc

autojump - wting

在终端的文件夹跳转非常麻烦,需要敲长长的路径。
alias 别名也不是很方便。
autojump 是通过记录进入过的目录到数据库来实现的,所以必须是曾经进入过的目录才能跳转。

安装 autojump,配置到 oh-my-zsh 中要重启永久生效;

$ sudo yum install autojump autojump-zsh -y

用法
只有打开过的目录 autojump 才会记录,所以使用时间越长,autojump 才会越智能。
可以使用 autojump 命令,或者使用短命令 j.

1.跳转到指定目录

j directoryName  

如果不知道目录全名,输入一部分,按Tab键就好,输错了也没关系,可以自动识别,非常强大。

⚡ root@finn # ~ $ j apps
/root/apps
⚡ root@finn # ~/apps $ j apps
/root/apps/autojump

Tab 键效果

⚡ root@finn # ~ $ j apps__(Tab 键自动添加了下划线, 输入数字回车则跳转指定目录)
apps__1__/root/apps           apps__2__/root/apps           apps__3__/root/apps           apps__4__/root/apps/autojump

->

⚡ root@finn # ~ $ j apps__4
/root/apps/autojump
⚡ root@finn # ~/apps/autojump $ 

2.跳转到指定目录的子目录

jc directoryName  

效果如下:

⚡ root@finn # ~/apps/autojump $ l
total 12K  
-rw-r--r-- 1 root root 11K 2019-10-24 02:39:45 dracula.zip
drwxr-xr-x 4 root root  89 2019-10-26 21:40:23 zsh-master/  
⚡ root@finn # ~/apps/autojump $ jc
/root/apps/autojump/zsh-master
⚡ root@finn # ~/apps/autojump/zsh-master $ 

3.查看权重

j --stat  

效果如下:

⚡ root@finn # ~ $ j --stat
22.4:    /root/apps/autojump/zsh-master  
22.4:    /root/.oh-my-zsh  
30.0:    /root/apps/autojump  
42.4:    /root/apps  
________________________________________

117:      total weight  
4:        number of entries  
0.00:     current directory weight

data:     /root/.local/share/autojump/autojump.txt  

可以通过修改autojump.txt的权重值, 产生不同的效果:

$ vim /root/.local/share/autojump/autojump.txt

4.或者查看帮助

⚡ root@finn # ~ $ j -h
usage: autojump [-h] [-a DIRECTORY] [-i [WEIGHT]] [-d [WEIGHT]] [--complete]  
                [--purge] [-s] [-v]
                [DIRECTORY [DIRECTORY ...]]

Automatically jump to directory passed as an argument.

positional arguments:  
  DIRECTORY             directory to jump to

optional arguments:  
  -h, --help            show this help message and exit
  -a DIRECTORY, --add DIRECTORY add path
  -i [WEIGHT], --increase [WEIGHT] increase current directory weight
  -d [WEIGHT], --decrease [WEIGHT] decrease current directory weight
  --complete            used for tab completion
  --purge               remove non-existent paths from database
  -s, --stat            show database entries and their key weights
  -v, --version         show version information

Please see autojump(1) man pages for full documentation.  

zsh-syntax-highlighting - zsh-users

这是一个命令高亮插件,输入为绿色时表示可用命令,路径带有下划线时表示可用路径。 插件安装:How to install

# 1.克隆到插件目录:
⚡ root@finn # ~ $ git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting

# 2.修改配置文件.zshrc:
⚡ root@finn # ~ $ vi ~/.zshrc

plugins=(git zsh-syntax-highlighting)

# 3.最后别忘了让配置生效
source .zshrc  

以上文章参考来自:
Linux 懒人工具 - autojump - zzpwestlife
centos7 安装zsh和使用oh-my-zsh - 摘星辰Li
Oh-My-Zsh的配置与使用 - 再见理想_
完美的Linux之【navi】使用笔记 - 我们都很努力着
利用Oh-My-Zsh打造你的超级终端 - 种瓜大爷


Finn

继续阅读此作者的更多文章