原文地址
https://zh.opensuse.org/SDB:Zsh
1 为什么要使用 Zsh?
为什么要使用 Mac OS X?因为它潮!它潮在哪儿了?终端还不一样是 Bash。比 Mac OS X 终端还潮的终端!要不要?
1.1 Zsh 相比 Bash 的优点?
要说优点,首先说缺点,缺点就是配置上太过复杂了。提供了太多的定制选项就会像SDB:字体显示一样,配置得漂亮与否,没法评价,因为任何人都能上手来搞两下。openSUSE 是主打易用性的系统,因此本文将尽量的降低难度,弱化定制选项的作用,而尽量去寻找一些还过得去的预制脚本。
根据 Zsh 官方网站的 FAQ, Zsh 相比 Bash 的优点(它没有明说,但很明显它就是对照着 Bash 开发的)是:
- 命令行编辑
- 可编程的补全:整合了 zsh 强大的通配和 shell 编程特性,
- 可将多行命令作为一个缓冲区编辑(文件也可以!),
- 变量编辑 (vared),
- 命令缓冲堆栈,
- 直接将文本打印到缓冲区以立即编辑 (print -z),
- 执行未绑定的命令,
- 两种风格的菜单补全,
- 变量,编辑功能和选项名称的补全,
- 变量和历史命令的内联展开。
- 通配 --- 异常强大,包括:
- 递归通配 (对比 find 命令),
- 文件属性限定符 (大小,类型,等等,也是对比 find 命令),
- 完整的变更和否定模式。
- 能处理多重重定向 (比 tee 命令简单)
- 大量定制选项
- 路径展开 (=foo -> /usr/bin/foo).
- 拼写,监视 (watch),时间和提示符消息的适应性很强(包括条件表达式)
- 目录命名
- 缜密的整形和浮点算法
- 控制矩阵 (包括反向下标)
- 关联矩阵 [键-散列值 (Hash) 映射]
- 拼写检查
2 安装
Zsh 已被 openSUSE 收录,是默认安装的 shell,只是大家一直没有用。如果已经卸载的,可以使用
sudo zypper in zsh
重新安装。
3 配置
正常情况下,在一个命令行环境中运行 zsh 就会弹出新手向导,对应该向导即可完成配置。
但我们不准备使用这个向导,而是准备使用 oh-my-zsh 这个项目的预制脚本。
oh my zsh 是一个 zsh 配置交流社区,主要通过 Github 来收录配置。安装后还可以每周自动更新(因为是 Git 嘛)。
下面以 Konsole 为例,Gnome terminal 或 Xterm 等可能有所差别,但原理相同。
3.1 下载 oh-my-zsh
3.1.1 自动安装
- curl 方法
curl -L [https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh](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](https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh) -O - | sh
3.1.2 手动安装
在 $USER 也就是你的私人主文件夹下:
- 安装 Git:
sudo zypper in git
- 撷取 oh-my-zsh
git clone [https://github.com/robbyrussell/oh-my-zsh.git](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
3.2 将 Zsh 设置为默认 Shell
常规方法:
chsh -s /bin/zsh
然后输入当前用户密码。不要使用 sudo 执行它,因为那样子换掉的是你 root 根用户的默认 shell,你的还是 bash。
但这种方法在 Konsole 中是行不通的。
3.2.1 Konsole 修改默认 Shell
“设置”-“编辑当前方案”-“常规”-“命令”,把 /bin/bash 改成 /bin/zsh。
顺路把图标也换了吧?用 Zsh 就要更个性一点么。
3.2.2Konsole 更换 Zsh 图标
下载这个文件 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 的“设置”-“编辑当前方案”-“图标”里面改图标。
3.3 配置 oh-my-zsh
3.3.1 主题
主题目录在 ~/.oh-my-zsh/themes,下面有好多主题,主题的预览在这里可以看到:
https://github.com/robbyrussell/oh-my-zsh/wiki/themes
应用主题的方法是:
vi .zshrc
修改 ZSH_THEME="miloshadzic" 为你想要的主题名称。
注意
有些主题是 256 色的,Konsole 默认是 16 色。如果颜色与预览不对的话,请见下面的 Konsole 256 色章节。
3.3.2 插件
插件目录在 ~/.oh-my-zsh/plugins,下面有好多插件,默认开启的是 Git 插件。应用插件的方法是:
vi .zshrc
可以看到 plugins=(git opensuse marguerite) 这样的字段,对应添加插件文件夹的名称就可以了。
openSUSE 相关的插件请见下面,目前主要有 编译服务 相关的插件和 zypper 相关的插件。
3.4 删除 oh-my-zsh
进入 ~/.oh-my-zsh/tools,下面有个 uninstall.sh,但是它没有执行权限,改一下:
chmod +x uninstall.sh
然后执行它:
./uninstall.sh
就会自动卸载掉 oh-my-zsh。
3.5 恢复 Bash
不想用 Zsh 了?很简单:
chsh -s /bin/bash
就换回来了。Konsole 一样要用上面的方法。
3.6 自定义别名(Alias)
在 ~/.oh-my-zsh/custom 下的 example.zsh 中可以定义你自己的别名,比如将 /home/marguerite/Public/home:MargueriteSu 这种长路径定义为一个简短好记的别名,比如:
mrepo=/home/marguerite/Public/home:MargueriteSu
4 定制
以下定制基于 oh-my-zsh,略加调整后可应用于原生的 Zsh。
4.1 Konsole 256 色
Konsole 原生是 16 色的,也就是只能显示像煤球黑,瞎眼白这样的纯色。
修改方法是“设置”-“编辑当前方案”-“环境”,将里面内容替换成 TERM=xterm-256color 即可。
4.2 Konsole 光标闪烁
“设置”-“编辑当前方案”-“高级”-“光标”-“闪烁光标”。
4.3 Konsole 字体
安装 M17N 仓库的 kde-oxygen-fonts 或 ubuntu-fonts,然后在
“设置”-“编辑当前方案”-“外观”-“字体”中修改,记得勾选“平滑字体”和“用粗体绘制强调色”。
注意
字体须选择 mono 类型的字体,也就是等宽字体。不用考虑汉字,汉字是用你安装的中文字体来显示的,详情见SDB:字体显示。
4.4 主题制作
4.4.1 Konsole 主题
oh-my-zsh 不是神,它设置不了你的终端颜色,只能使用现有的终端颜色。因此需要先制作一个 Konsole 主题来规定颜色。
“设置”-“编辑当前配置方案”-“外观”-“新建”,输入一个名字,“背景透明度”和“背景图片”自选。
4.4.1.1 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 定义的再漂亮,也没法用于显示文件夹。
4.4.1.2 配色指南
有很多在线分享配色的网站,比较著名的是 colourlovers 和 Adobe kuler。
- 10 Resources for Creating Website Color Schemes
- 10 Sites to Play with Colors and Create Color Palettes
这两个链接几乎囊括了全部类似网站。自己审美有问题配不好的话,可以使用这些网站上的分享。
但是有一个缺陷就是它们几乎都没有提供强烈色,也就是相近色,折衷的方法是使用 KColorChooser 自己来微调出强烈色:
在 KColorChooser(内嵌在 Konsole 的颜色配置中,不用另开)中输入了一个获取到的网页颜色代码 (#abcdef) 后,界面上有一个条带,显示了该颜色的所有强度的颜色,挑一个就好。
4.4.1.3 导出配色
保存之后,新建的配色方案放在 $USER 也就是你的个人主文件夹下的 ~/.kde4/share/apps/konsole/ 下,名称为 *.colorscheme。将它上传到比如 kde-look.org 这样的网站就可以与他人共享你的配色啦。
4.4.2 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 代表的颜色来显示。颜色的说明见上,必须使用小写标准英文名称。
4.4.2.1 提示符变量
除非想显示固定文字,否则提示符中都应该使用变量:
常用
- %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 加粗
- %{[文字]%} 完全不显示(这回知道颜色语法的意义了吧。)
4.4.2.2 文字符号
你可以使用文字符号来替换 bash 中默认的 "~#:",一些可用的文字符号可见:
比如我的:
18:28:45 marguerite at ~/Downloads say:
卐
你也可以用 ☠ ☯ ☢ 来美化你的哦。
4.5 插件制作
制作插件的方法是在 ~/.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"
4.5.1 冲突检测
如果你定义的别名和系统中有的相冲突,那两者都没法使用,所以定义前需要检测一下 /bin 和 /usr/bin 以及或有的 /usr/local/bin 下有没有相关的指令,检测的方法是到相应的文件夹中:
ls | grep 你要检测的命令
其中 ls 是列出全部内容,然后通过一个管道 "|" 把列出的结果传递给 grep,grep 从中提取出你要检测的命令并最终显示。
4.6 高级插件
当然,Zsh 的功能不止这些,它可以配合 Shell 语法或其他脚本语言如 Perl、Python、Ruby 等做到任何事情,比如电源显示,比如网络连接强度,可以说是命令行的 Conky 了。具体制作方法要求比较高,需要懂 Shell 语法或脚本语言,因此不一一赘述。作为启蒙,有兴趣的人可以去看参考链接三的那篇文章。
4.6.1 欢迎添加
4.7 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 | 解除某软件包的版本锁定 |
4.7.1 OBS 仓库全名的自动补全
注意
这是错的。会导致 Konsole 瞬间关闭。但原理对。只是需要将 complete 移植到 zsh。
sudo cp -r /usr/lib/osc/complete /etc/zsh_completions.d
5 高级应用
- 自动补全 教你使用zsh之=======zsh的文件名替换和自动补全
- 创建自己的自动补全 Easy Zsh Auto Completion