3
19
2012
20

zsh 命令行编辑技巧三则

本文来自依云's Blog,转载请注明。

zsh 的命令行编辑使用的是 Zsh Line Editor(Zle),功能比 readline 强大不少,只是大量好用的功能都深埋于文档中,难得见识到。最近在看A User's Guide to the Z-Shell,虽然内容有些旧了,但依旧很有用。

首先说一点,以下内容均假定使用的是 Emacs 式键绑定。

暂停当前命令的编辑,先执行点其它命令。这个功能叫push-line,默认绑定在Alt-q。另有一个叫做push-line-or-edit的 widget,我把它绑过来了:

bindkey "\eq" push-line-or-edit

push-line widget 会将当前命令行上的内容放到一个栈上,显示一个新的提示符让你来执行点别的东西。比如刚写了一个长命令的一半,却发现当前目录不对。怎么办呢?readline 里我只好先Ctrl-u,执行之后再Ctrl-y粘贴回来。偶尔会找不到之前 kill 的内容。在 Zsh 里,按下Alt-q,当前命令暂存起来,你可以执行点别的命令,再显示命令提示符时,之前 push 走的命令内容会 pop 回来。而且这个操作是可以嵌套的,因为这是一个

push-line-or-edit widget 多了个 or-edit 后缀。当输入一个if或者for这样的命令时,你可以写成多行,zsh 会自动判断出你的命令尚未写完,显示$PS2提示符。这时,如果想修改之前的某一行怎么办呢?push-line-or-edit widget 会把这些行命令变成一个不带有$PS2提示符的多行命令,默认键绑定中,使用Ctrl-p/n或者方向键移动即可。这个就是 zsh 的多行编辑能力。如果你喜欢使用 zsh 编辑的话,可以试试zed这个运行于 zsh 中的简单文本编辑器:

autoload zed
zed some_small_text_file

按顺序执行若干条历史记录中的命令。比如我读取 3G 网卡短信使用如下的命令序列:

gnokii --smsreader
gnokii --getsms SM 0 end -f sms
smsmboxproc < sms > sms.mbox
mutt -f sms.mbox

如果使用Ctrl-r搜索历史的话,每条命令都搜索岂不麻烦?所以有了accept-line-and-down-history这个 widget,默认绑定于Ctrl-o。先在历史记录里找到第一条需要的命令,按下Ctrl-o,命令执行后,历史记录中的下一条就会出现了。然后接着按Ctrl-o,直到需要执行的命令序列到达最后一条,这次该按Enter了。

最后一个,你是不是经常往命令行上粘贴网址?是的话,你应该知道,网址得用引号括起来,以防止有些字符被 shell 解释了。zsh 带了个功能,可以检测出当前输入的是否是 URL,如果是的话就自动转义那些特殊字符。这样往命令行上粘贴 URL 时就不需要事先打好引号了。使用如下命令启用:

autoload -U url-quote-magic
zle -N self-insert url-quote-magic
Category: shell | Tags: zsh shell | Read Count: 16972
Zind 说:
Mar 27, 2012 03:07:48 PM

autoload zed
zed some_small_text_file
----------------------------
这个也是要写入 .zshrc 中的吧?
为什么要写进去之后,再 source ~/.zshrc 时,zsh 会卡住不动?

Avatar_small
依云 说:
Mar 27, 2012 04:48:31 PM

因为 zed 就是文本编辑器啊,不应该写到 zshrc 里。autoload 可以写进去。

Zind 说:
Mar 27, 2012 08:37:55 PM

晕……
我纳闷呢,怎么会有 zed some_small_text_file 这么奇怪的东东。
我当时在 zsh 中输入 zed,提示没有这个命令。
现在发现是我这边有 bug:在同样用户,同样 shell,同样环境下,一个 termianl tab 中有 zed 命令,其它几个没有。
定位中。

Zind 说:
Mar 28, 2012 01:03:30 PM

是我的问题。
直接输 zed 不行。要先将 autoload zed 写入 ~/.zshrc,再 source 后,才可用。
-------------------------------------
PS.
1. 博客很慢,有时打不开,被 GF_W 认证了?
2. E-mail 从来没有收到评论通知。

Avatar_small
依云 说:
Mar 28, 2012 07:26:11 PM

1. 是的,站长正准备尝试通过迁移解决这个问题,而我早已放弃直连了;
2. 这个不清楚,也许只有注册用户才会收到邮件?

yywill 说:
Jun 06, 2012 02:15:52 PM

好东西。不过还是推荐作者把博客做成github的wiki把。 这样也方便大家索引和push改变。

我以前也玩过博客。不过说实话……博客太不靠谱了。自己的域名……多年以后自己忘记了,博客和文章也就都不在了。

Avatar_small
依云 说:
Jun 06, 2012 04:58:24 PM

Github Wiki 不喜欢。我倒是想过使用 gh-pages 来实现可协作的文档系统。

博客的话,如果一直写下去,是不会遗忘的。相反,git repo 更容易遗忘。我今天刚刚在邮件的提醒下修复一个 issue,而那个 repo 的上一次提交已经是 13 个月前了。

yywill 说:
Jun 06, 2012 06:01:28 PM

博客是要钱的吧…… 会有一天忘记付钱 不想付钱的…… 哈哈

Avatar_small
依云 说:
Jun 06, 2012 08:58:10 PM

不是所有博客都要钱的,比如这里这个,比如建在 gae/github/etc 上的。

yywill 说:
Jun 08, 2012 10:09:41 AM

不是说没有免费的。免费的总是不能长久。以前的blogspot被封,msnspace关闭,wordpress.com也被封了。 总是需要不停地迁移,有的时候真的很烦。

尤其烦的是,有的时候还需要迁移软件,从z-blog到wordpress……而wordpress最近又有下滑的趋势……

很多时候,找一个安心能够写的,但是不需啊哟折腾的,太难了。

Avatar_small
依云 说:
Jun 08, 2012 01:39:01 PM

中国特色嘛。嗯,myspace 那个是 MS 的问题。

wood 说:
Nov 16, 2014 09:22:17 AM

zsh vi模式绑定,有个问题:
当用ESC键切换的时候,总是要等那么一下下,显得比较迟钝。。
请问,有没有解决“迟钝”的办法咯?

Avatar_small
依云 说:
Nov 16, 2014 10:23:32 AM

设置 KEYTIMEOUT=1 (10ms,默认是 0.4s)试试。

Smallville 说:
Aug 18, 2017 09:16:59 AM

求助:
用你的zshrc,应该是在github下载的,今天更新后
zsh: parse error near `>'
怎么处理?

Smallville 说:
Aug 18, 2017 09:59:27 AM

部分命令会这样,如systemctl

Avatar_small
依云 说:
Aug 18, 2017 11:07:08 AM

是执行命令的时候?没有说是什么文件或者函数吗?

Smallville 说:
Aug 18, 2017 11:33:50 AM

非常抱歉, 现在我测试没问题了,(记得但当时是重启后还不行的。或许我忘了),so sorry , 呜呜,,,
昨天临时用了这个人的:
https://github.com/slashbeast/things/blob/master/configs/DOTzshrc
发现他有两个功能有点cool的,能否借用?
比如输入reboot回车,会自动提示:
zsh: sure you want to run 'sudo reboot' [yN]?
还有一个,cp zshrc .zshrc 会提示:
'zshrc' -> '.zshrc'

Avatar_small
依云 说:
Aug 18, 2017 11:49:19 AM

reboot 在登录用户唯一的时候是不需要另外授权的呀。
而且用户不一定有 reboot 这个命令。

cp 那个只是个 cp -iv 的别名啦。这种别名有安全隐患所以我没有使用的。考虑这样一种情况:你一直在使用各种带确认的别名。然后某一天别名没有生效(比如因为换了个还没有配置的系统,或者是配置出现了问题等),你还是直接复制 / 移动,以为如果会覆盖文件的时候会有机会反悔,而其实并没有,你就在未注意的情况下覆盖掉了文件。

Smallville 说:
Aug 18, 2017 11:58:40 AM

好的,明白了,安心用你这个好了。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

| Theme: Aeros 2.0 by TheBuckmaker.com