Linux Bash-Zsh 快捷键模式 Emacs-Vim
ZSH开发指南
zsh - Prompt Expansion
13 Prompt Expansion (zsh)
0=${(%):-%N}
%N The name of the script If there is none, this is equivalent to the parameter $0
source ${0:A:h}/zsh.d/.zplug.zsh
:A 等价于 readlink 读取原文件的地址
:h 字符串截取 目录
zsh compinit: insecure directories, run compaudit for list.
Ignore insecure directories and continue [y] or abort compinit [n]?
Hence, the solution implies fixing one (or all) of the following:
- setting the current user as the owner of all the directories/subdirectories/files in cause:
compaudit | xargs chown -R "$(whoami)"
- removing write permissions for group/others for the files in cause:
compaudit | xargs chmod go-w
- Another approach would be to skip these checks by using
compinit -u
目录文件名截取
% filepath=/a/b/c.x
# :A 读取原文件的路径,等价于readlink
# :h 是取目录名,即最后一个 / 之前的部分,如果没有 / 则为 .
% echo ${filepath:h}
/a/b
# :t 是取文件名,即最后一个 / 之后的部分,如果没有 / 则为字符串本身
% echo ${filepath:t}
c.x
# :e 是取文件扩展名,即文件名中最后一个点之后的部分,如果没有点则为空
% echo ${filepath:e}
x
# :r 是去掉末尾扩展名的路径
% echo ${filepath:r}
/a/b/c
Bash 和 zsh 用法简明对照表
Bash 用法 | Zsh 用法 | 说明 |
---|---|---|
"$var" | $var | 避免变量中有空格导致异常 |
"$@" | $* | 避免变量中有空格导致异常 |
"${array[@]}" | $array | 取数组所有元素,@ 可改成 * |
"${#array[@]}" | $#array | 取数组中元素个数,@ 可改成 * |
"${array[n - 1]}" | $array[n] | 取数组第 n 个元素,bash 从 0 开始,zsh 从 1 开始 |
"$array" | $array[1] | Bash 中的 $array 是取数组的第一个元素 |
echo a*b | echo "a*b" | Zsh 默认配置中,通配符如果匹配不到文件会报错 |
if true; then :; fi | if true {} | Zsh 中不需要使用 : 作为空语句 |
[ "$var" == value ] | [[ $var == value ]] | Zsh 中的 [ ] 里不支持 == ,一律用 [[ ]] |
ls \| tee file \| less | ls > file \| less | Zsh 中不需要用 tee 即可实现相同功能 |
Bash 环境
多数时候我们用的是 Bash, 比如个人的 Linux 不愿去定制,远程服务器的由不得你去定制,所以就从 Bash 说起。
默认键绑定 emacs, 操作是 ctrl-x, ctrl-e
在默认的 Bash 环境下,只要在命令行中按下 ctrl-x, ctrl-e 就会把当前命令的内容调入到环境变量 $EDITOR 指示的编辑器(默认为 emacs)去编辑,编辑后保存退出就会立即执行。
如果未安装 Emacs 编辑器,在按下 ctrl-x, ctrl-e 会得到如下提示
[vagrant@localhost ~]$
-bash: emacs: command not found
如果希望使用 vi 来编辑当前命令,就需要设置 EDITOR 环境变量,比如在 .bashrc 中加入
export EDITOR=vi
那么在命令行中按下 ctrl-x, ctrl-e 使用打开 vi 来编辑当前命令。
注:Emacs 要用 ctrl-x, ctrl-c, 再回答 y, 命令保存到临时文中; 而 vi 的相应操作是 :wq, 至少这个操作上 vi 要简洁些。
可以用命令 bind -p | grep -F "\C-x\C-e 查看 ctrl-x, ctrl-e 是执行了 Readline 命令 edit-and-execute-command
$ bind -p | grep -F "\C-x\C-e"
"\C-x\C-e": edit-and-execute-command
更多:bind -p 可以显示所有的键绑定,bind -p | grep -F "\C" 可查看含 ctrl 按键的绑定。
键绑定为 vi 时,操作是正常模式下按 v 键
可以用命令 set -o vi 切换到 Vi 键绑定。切回到 emacs 键绑定用 set -o emacs。
Vi 键绑定时命令行就像是一个简单的行编辑器,Esc 在正常模式与输入模式间切换,如果要打开 Vi 来编辑当前命令只需在正常模式按下 v, 环境变量 $EDITOR 指定的编辑器(默认为 Vi ) 载入当前命令进行编辑。
如果对 Emacs 青睐有加的话,可以设置 $EDITOR 为 emacs, 这时按 v 键打开的就是 Emacs 编辑器。
Zsh 环境
快捷键设置
设置文件位置
绑定的设置可以写入 .zshrc 文件中。如果使用 oh-my-zsh ,配置还可以写入 ~/.oh-my-zsh/lib/key-bindings.zsh 中。
转换序列
在使用 bindkey 命令时,一帮第一个参数使用对应快捷键的 CSI 序列 ,如果想知道某种快捷组合键的 CSI 序列,可以有如下两种方法:
先按 Ctrl-V 然后再按组合键,如 Ctrl-A
输入 cat > /dev/null ,之后输入组合键
设置命令
前后移动一个单词
bindkey '^[^[[C' emacs-forward-word # Alt-Right
bindkey '^[^[[D' emacs-backward-word # Alt-Left
or
bindkey '^[Oc' emacs-forward-word # Ctrl-Right
bindkey '^[Od' emacs-backward-word # Ctrl-Left
同 Bash 的内置 bind 命令一样,Zsh 也有自己内置的键绑定命令 bindkey。而且也有相应的 emaces 和 vi 键绑定,切换的命令分别是 bindkey -e, 和 bindkey -v。
默认情况下,不管是 emacs 还是 vi 的按键绑定,ctrl-x, ctrl-e 和 v 键都不起作用,所以都得定制。针对两种键绑定类型分别为:
emacs 键绑定
默认的,或使用了 bindkey -e
指定为 emacs 键绑定,可以在 ~/.zshrc 中加入
autoload -z edit-command-line
zle -N edit-command-line
bindkey "^X^E" edit-command-line
source ~/.zshrc 后,便可按 ctrl-x, ctrl-e 打开 $EDITOR 指定的编辑器(默认为 vi) 来编辑当前命令
vi 键绑定
用 bindkey -v
切换键绑定到 vi, 在 ~/.zshrc 加入
autoload -z edit-command-line
zle -N edit-command-line
bindkey -M vicmd v edit-command-line
然后 source ~/.zshrc 后,在命令行的 vi 命令模式下按 v 键会打开$EDITOR 指定的编辑器(默认为 vi) 来编辑当前命令。
注意:在 Zsh 中,不管是 emacs 还是 vi 键绑定,未设置 $EDITOR 的话,默认都是 vi, 这一点与 Bash 是不同的。
bindkey 的几个相关命令:bindkey -l, bindkey -lL, bindkey -L, bindkey --, bindkey -a
总结
最好是设置环境变量 $EDITOR 明确指定编辑器是 emacs 还是 vi。
Bash emacs 键绑定按 ctrl-x, ctrl-e 打开编辑器载入命令,vi 键绑定按 v 键打开编辑器
Zsh 需要自行绑定按钮到 edit-command-line 命令
emacs 的保存退出命令是 ctrl-x, ctrl-c, 回答 y 退出,vi 就用 :wq 退出
配置只单单按v 键打开编辑器更容易产生误操作,也可能会与 vi 的可视模式混淆
任何情况下,不管是 Bash/Zsh, 无论何种键绑定都可以使用 fc 命令调用 EDITOR 来编辑最后一条执行的命令。
参考:
Vi mode in Bash
Zsh Line Editor
Zsh Zle Functions
Editing long commands in your shell