SDB:Zsh

跳转至: 导航, 搜索
Zsh 是一个终端。简单来讲就是几乎所有类 Unix 系统的默认终端 Bash 的改良版。

Zsh marguerite.png

为什么要使用 Zsh?

为什么要使用 Mac OS X?因为它潮!它潮在哪儿了?终端还不一样是 Bash。比 Mac OS X 终端还潮的终端!要不要?

Zsh 相比 Bash 的优点?

要说优点,首先说缺点,缺点就是配置上太过复杂了。提供了太多的定制选项就会像SDB:字体显示一样,配置得漂亮与否,没法评价,因为任何人都能上手来搞两下。openSUSE 是主打易用性的系统,因此本文将尽量的降低难度,弱化定制选项的作用,而尽量去寻找一些还过得去的预制脚本。

根据 Zsh 官方网站的 FAQ, Zsh 相比 Bash 的优点(它没有明说,但很明显它就是对照着 Bash 开发的)是:

  • 命令行编辑
    • 可编程的补全:整合了 zsh 强大的通配和 shell 编程特性,
    • 可将多行命令作为一个缓冲区编辑(文件也可以!),
    • 变量编辑 (vared),
    • 命令缓冲堆栈,
    • 直接将文本打印到缓冲区以立即编辑 (print -z),
    • 执行未绑定的命令,
    • 两种风格的菜单补全,
    • 变量,编辑功能和选项名称的补全,
    • 变量和历史命令的内联展开。
  • 通配 --- 异常强大,包括:
    • 递归通配 (对比 find 命令),
    • 文件属性限定符 (大小,类型,等等,也是对比 find 命令),
    • 完整的变更和否定模式。
  • 能处理多重重定向 (比 tee 命令简单)
  • 大量定制选项
  • 路径展开 (=foo -> /usr/bin/foo).
  • 拼写,监视 (watch),时间和提示符消息的适应性很强(包括条件表达式)
  • 目录命名
  • 缜密的整形和浮点算法
  • 控制矩阵 (包括反向下标)
  • 关联矩阵 [键-散列值 (Hash) 映射]
  • 拼写检查

安装

Zsh 已被 openSUSE 收录,是默认安装的 shell,只是大家一直没有用。如果已经卸载的,可以使用

sudo zypper in zsh

重新安装。

配置

正常情况下,在一个命令行环境中运行 zsh 就会弹出新手向导,对应该向导即可完成配置。

但我们不准备使用这个向导,而是准备使用 oh-my-zsh 这个项目的预制脚本。

oh my zsh 是一个 zsh 配置交流社区,主要通过 Github 来收录配置。安装后还可以每周自动更新(因为是 Git 嘛)。

下面以 Konsole 为例,Gnome terminal 或 Xterm 等可能有所差别,但原理相同。

下载 oh-my-zsh

自动安装

  • curl 方法
curl -L https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh | sh
  • wget 方法(有些人的系统上没装 curl)
wget --no-check-certificate https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh -O - | sh

手动安装

在 $USER 也就是你的私人主文件夹下:

  • 安装 Git:
sudo zypper in git
  • 撷取 oh-my-zsh
git clone https://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
  • 备份现有的 zsh 配置
mv .zshrc .zshrc.orig
  • 使用 oh-my-zsh 的配置
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc

将 Zsh 设置为默认 Shell

常规方法:

chsh -s /bin/zsh

然后输入当前用户密码。不要使用 sudo 执行它,因为那样子换掉的是你 root 根用户的默认 shell,你的还是 bash。

但这种方法在 Konsole 中是行不通的。

Konsole 修改默认 Shell

「设置」-「编辑当前方案」-「常规」-「命令」,把 /bin/bash 改成 /bin/zsh。

顺路把图标也换了吧?用 Zsh 就要更个性一点么。

Konsole 更换 Zsh 图标

Zsh icon.png

下载这个文件 zsh.svgz,然后安装 rsvg-view 或 inkscape。

rsvg-convert -w 256 zsh.svgz -o 256.png

inkscape 是将 svgz 打开后,使用「文件」-「导出」-「页面」,然后填写尺寸即可。

将 256 改为 16,22,24,32,48,64,72,96,128,会制作出各种格式的 png 图标。然后将对应格式的图标放到 /usr/share/icons/hicolor/256x256/apps 文件夹下,例如:

sudo cp -r 256.png /usr/share/icons/hicolor/256x256/apps/zsh.png

将 svgz 复制到 /usr/share/icons/hicolor/scalable/apps 文件夹下。

然后在 Konsole 的「设置」-「编辑当前方案」-「图标」里面改图标。

配置 oh-my-zsh

主题

主题目录在 ~/.oh-my-zsh/themes,下面有好多主题,主题的预览在这里可以看到:

https://github.com/robbyrussell/oh-my-zsh/wiki/themes

应用主题的方法是:

vi .zshrc

修改 ZSH_THEME="miloshadzic" 为你想要的主题名称。

注意: 有些主题是 256 色的,Konsole 默认是 16 色。如果颜色与预览不对的话,请见下面的 Konsole 256 色章节。

插件

插件目录在 ~/.oh-my-zsh/plugins,下面有好多插件,默认开启的是 Git 插件。应用插件的方法是:

vi .zshrc

可以看到 plugins=(git opensuse marguerite) 这样的字段,对应添加插件文件夹的名称就可以了。

openSUSE 相关的插件请见下面,目前主要有 构建服务 相关的插件和 zypper 相关的插件。

删除 oh-my-zsh

进入 ~/.oh-my-zsh/tools,下面有个 uninstall.sh,但是它没有执行权限,改一下:

chmod +x uninstall.sh

然后执行它:

./uninstall.sh

就会自动卸载掉 oh-my-zsh。

恢复 Bash

不想用 Zsh 了?很简单:

chsh -s /bin/bash

就换回来了。Konsole 一样要用上面的方法。

自定义别名(Alias)

在 ~/.oh-my-zsh/custom 下的 example.zsh 中可以定义你自己的别名,比如将 /home/marguerite/Public/home:MargueriteSu 这种长路径定义为一个简短好记的别名,比如:

mrepo=/home/marguerite/Public/home:MargueriteSu

定制

以下定制基于 oh-my-zsh,略加调整后可应用于原生的 Zsh。

Konsole 256 色

Konsole 原生是 16 色的,也就是只能显示像煤球黑,瞎眼白这样的纯色。

修改方法是「设置」-「编辑当前方案」-「环境」,将里面内容替换成 TERM=xterm-256color 即可。

Konsole 光标闪烁

「设置」-「编辑当前方案」-「高级」-「光标」-「闪烁光标」。

Konsole 字体

安装 M17N 仓库的 kde-oxygen-fonts 或 ubuntu-fonts,然后在

「设置」-「编辑当前方案」-「外观」-「字体」中修改,记得勾选「平滑字体」和「用粗体绘制强调色」。

注意: 字体须选择 mono 类型的字体,也就是等宽字体。不用考虑汉字,汉字是用你安装的中文字体来显示的,详情见SDB:字体显示

主题制作

Konsole 主题

oh-my-zsh 不是神,它设置不了你的终端颜色,只能使用现有的终端颜色。因此需要先制作一个 Konsole 主题来规定颜色。

「设置」-「编辑当前配置方案」-「外观」-「新建」,输入一个名字,「背景透明度」和「背景图片」自选。

Linux 终端配色机制

首先它只有 20 个颜色,前面所谓的 256 色,指的是能够显示 256 种颜色,而不是可以使用 256 个颜色。

分别是:前景 (foreground)、背景 (background)、黑 (Black)、红 (Red)、绿 (Green)、黄 (Yellow)、蓝 (Blue)、品红 (Magenta)、青 (Cyan)、白 (White) 以及它们分别对应的强烈色版本。

这里需要注意的是它们的原始名称原始位置,至于这个名称代表的名义颜色则不是很重要,比如你将「红」(Red) 定义为 #9c0,后者实际上是 openSUSE 淡绿,但你在下面的 oh-my-zsh 主题中想提到这个 openSUSE 淡绿的时候,还是要用 %{$fgcolor[red]%} 也就是「红」而不是「绿」(green) 来提它。

换句话说,你可以将它们理解为 8 个占位符,颜色 1 ~ 颜色 8,只是这些占位符的名字就叫做红、绿等等。而占位符的位置是非常重要的,比如强烈蓝,实际上的位置是颜色 13,颜色 9 ~ 颜色 16 都是强烈色(前景背景不算进颜色序列中),用来在加粗、语法高亮、选中等特殊情况下显示。而 KDE 就规定了使用颜色 13 来显示文件夹,那么你把蓝,也就是颜色 5 定义的再漂亮,也没法用于显示文件夹。

配色指南

有很多在线分享配色的网站,比较著名的是 colourloversAdobe kuler

这两个链接几乎囊括了全部类似网站。自己审美有问题配不好的话,可以使用这些网站上的分享。

但是有一个缺陷就是它们几乎都没有提供强烈色,也就是相近色,折衷的方法是使用 KColorChooser 自己来微调出强烈色:

在 KColorChooser(内嵌在 Konsole 的颜色配置中,不用另开)中输入了一个获取到的网页颜色代码 (#abcdef) 后,界面上有一个条带,显示了该颜色的所有强度的颜色,挑一个就好。

导出配色

保存之后,新建的配色方案放在 $USER 也就是你的个人主文件夹下的 ~/.kde4/share/apps/konsole/ 下,名称为 *.colorscheme。将它上传到比如 kde-look.org 这样的网站就可以与他人共享你的配色啦。

oh-my-zsh 主题

制作 oh-my-zsh 主题的方法是在 ~/.oh-my-zsh/themes/ 下面放一个名为 主题名.zsh-theme 的纯文本文件。

由于颜色不能在这里定义,而只能在这里使用,我们需要定义的实际上只有 oh-my-zsh 特有的一些补全功能的颜色显示和提示符的格式。比如我的象征第四帝国的万字提示符 卐 就是在这里定义的。下面是一个样板:

 # Name:
 # Version:
 # License:
 # Author:
 # Description:

 ZSH_THEME_GIT_PROMPT_PREFIX="%{$reset_color%}%{$fg[blue]%}"
 ZSH_THEME_GIT_PROMPT_SUFFIX="%{$reset_color%} "
 ZSH_THEME_GIT_PROMPT_DIRTY="%{$fg[yellow]%}⚡%{$reset_color%}"
 ZSH_THEME_GIT_PROMPT_CLEAN=""

 PROMPT='%{$fg[yellow]%}%*%{$reset_color%} %{$fg[magenta]%}%n%{$reset_color%} at %{$fg[green]%}%~%{$reset_color%} $(git_prompt_info)say%{$fg[cyan]%}:
卐 %{$reset_color%}'

以 # 开头的是注释,不会显示。

ZSH_THEME_GIT_PROMPT_PREFIX 这个是在 ~/.oh-my-zsh/lib 下面的定义的宏,具体支持哪些也可以去下面看。定制的这个宏的显示只有在启用了相应插件的情况下才会有用。

颜色语法:%{$fg[yellow]%} 和 %{$reset_color%} 是一对,中间夹住的文字或符号会用 yellow 代表的颜色来显示。颜色的说明见上,必须使用小写标准英文名称。

提示符变量

除非想显示固定文字,否则提示符中都应该使用变量:

常用

  •  %n 用户名
  •  %M 主机名(主机名可以在「YaST」-「网络设备」-「网络服务」中设置,比如 marguerite@earth 的 earth 而不用默认的 linux)
  •  %m 主机名,截取第一个空格前的内容(比如主机名为 the underground world,那么只有 the 会显示)
  •  %l 当前 tty(虚拟终端中没用,只有 init 3 模式下才有用)
  •  %? 最后使用的命令的返回结果
  •  %# 基于用户权限的提示符,root 用户返回 #,其他用户返回 %。(需要当前用户和根用户的 Shell 都是 zsh,不然 root 用户的时候用的还是 bash,就没有意义)

时间

  •  %T 系统时间 HH:MM(小时:分钟 格式)
  •  %* 系统时间 HH:MM:SS(小时:分钟:秒 格式)
  •  %D 系统日期 YY-MM-DD(年-月-日 格式)

路径

  •  %~ 当前所在工作路径,要是用户根目录的话则直接显示 ~
  •  %d 主要用于显示特定级数的文件夹,比如 %1d 在 /home/marguerite/Downloads 时只会显示 Downloads,%-1d 则无论何时都显示成 /

格式化

  •  %U[文字]%u 下划线(注意,前面的字母是大写,后面的是小写)
  •  %B[文字]%b 加粗
  •  %{[文字]%} 完全不显示(这回知道颜色语法的意义了吧。)
文字符号

你可以使用文字符号来替换 bash 中默认的 "~#:",一些可用的文字符号可见:

Funny Cool Text Symbols

比如我的:

18:28:45 marguerite at ~/Downloads say:
卐 

你也可以用 ☠ ☯ ☢ 来美化你的哦。

插件制作

制作插件的方法是在 ~/.oh-my-zsh/plugins 下面创建一个名称叫「插件名」的文件夹,文件夹中是一个名为 插件名.plugin.zsh 的纯文本文件。

插件主要用到是 Shell 语法的 alias(别名)机制。也就是说将复杂命令简单化。比如这条命令:

osc build openSUSE_12.2 x86_64 presage.spec --local

通过定制 Shell 变量和 alias 机制:

## Get openSUSE Version
VERSION=`cat /etc/SuSE-release | grep VERSION | cut -d ' ' -f 3`
ARCH=`uname -m`
# work around for i686 kernel.
test "$ARCH" = i686 && ARCH=i586
alias bu="osc build --local openSUSE_$VERSION $ARCH"

就可以简化为:

bu presage.spec

后面的 presage.spec 是可以自动补全的,你只需要输入 p + [tab] + s 就可以了。这样,原来的 41 个字母(51 - 10 因为 spec 能自动补全,如果应用了 osc 的自动补全的话还可以少,但无论如何不会少于 4)就简化为了 4 个字母。

定义变量没办法讲,主要都是基本的终端命令,比如 ls,grep,cat,sed,test,echo 等以及管道也就是 "|" 符号的运用。基本语法就是定义变量的等号 "=" 两边都必须顶住,使用变量要加 $。然后 ' " ` 标点的嵌套使用,以及基本处理原则就是先出现的先处理,同行的从左到右处理。

alias 的语法是:

alias 你要定义的命令="原始命令"

它可以定义任何不冲突的东西,比如:

alias m="marguerite"

冲突检测

如果你定义的别名和系统中有的相冲突,那两者都没法使用,所以定义前需要检测一下 /bin 和 /usr/bin 以及或有的 /usr/local/bin 下有没有相关的指令,检测的方法是到相应的文件夹中:

ls | grep 你要检测的命令

其中 ls 是列出全部内容,然后通过一个管道 "|" 把列出的结果传递给 grep,grep 从中提取出你要检测的命令并最终显示。

高级插件

当然,Zsh 的功能不止这些,它可以配合 Shell 语法或其他脚本语言如 Perl、Python、Ruby 等做到任何事情,比如电源显示,比如网络连接强度,可以说是命令行的 Conky 了。具体制作方法要求比较高,需要懂 Shell 语法或脚本语言,因此不一一赘述。作为启蒙,有兴趣的人可以去看参考链接三的那篇文章。

欢迎添加

openSUSE 插件

可从 marguerite's oh-my-zsh 取得该插件。(因为官方 oh-my-zsh 暂停扩容了,合并不进去)

目前有 osc 的插件和 zypper 的插件,基本命令如下:

  • osc 相关
命令 用法 用途
bu bu example.spec 本地编译软件包
change change 书写软件包修订日志
add add example-version.tar.gz 添加文件到构建服务上传序列
del del example.patch 删除项目控制的某个文件
rdel rdel example_project example_package 远程从 OBS 上删除软件包
commit commit 上传构建服务上传序列的内容到 OBS 构建服务进行编译
submit submit source_project source_package destination_project 把软件包提交给某个仓库
status status 查看当前构建服务上传序列和文件修订情况
viewlog viewlog 查看本地编译日志,用于排错
mkpac mkpac package 新建软件包项目用于制作软件包
fork fork orig_prj orig_pkg dest_prj 派生一个软件包
get get prj pkg 从服务器上撷取一个软件包的编译环境
kick kick prj pkg 会对相应软件包发送一个 deleterequest
getrpm getrpm prj pkg arch 获取相应的 rpm
wiperpm wiperpm prj pkg 从服务器上删除生成的 rpm
prjmeta prjmeta project 修改项目元数据
pkgmeta pkgmeta package 修改软件包元数据
obssearch osbsearch something 在 OBS 上搜索软件包、项目等
restore restore prj pkg 恢复之前删除的软件包
update update 更新当前编译环境,与服务器同步
list_my list_my 列出你介入的 request
accept accept ID 接受某 ID 的请求
reject reject ID 拒绝某 ID 的请求
okrev okrev ID 复核同意
norev norev ID 复核拒绝
  • zypper 相关
命令 用法 用途
zpdup zpdup 系统升级
zpref zpref 刷新所有软件源
zpin zpin package 安装软件包
zprm zprm package 删除软件包
zpup zpup (package) 更新软件包或系统更新
zpar zpar repo_url repo_nick 添加软件源
zprr zprr repo_nick 删除软件源
zplr zplr 列出所有软件源
zpmr zpmr repo 修改软件源
zppa zppa patch 给系统打补丁
zplu zplu 列出可用的更新包
zplp zplp 列出需要且可用的补丁
zpse zpse pkg 搜索软件包
zpal zpal pkg 将软件包锁定在当前版本
zprl zprl pkg 解除某软件包的版本锁定

OBS 仓库全名的自动补全

注意: 这是错的。会导致 Konsole 瞬间关闭。但原理对。只是需要将 complete 移植到 zsh。
sudo cp -r /usr/lib/osc/complete /etc/zsh_completions.d

高级应用

作者

User:MargueriteSu

参考链接