历史命令归纳

之前在<<Linux 101 Hacks>>的总结中已经涉及到了一点点点的history方面的内容了 ,本篇是想对编辑history的几种工具小结一下 . 这上面举了很多的例子,看不懂文字直接看例子就可以了.

再来说几句那几个常见的历史的变量.
HISTSIZE : 决定了在某次会话间历史列表中保存的事件条目.
当从当前shell中退出时 , 最近执行的命令将保存在HISTFILE变量执行的文件中(默认是~/.bash_history) .

HISTFILESIZE : 决定了保存在HISTFILE中的历史行数(不一定与HISTSIZE相同) .
在PS1中 , 若加入\! , 即可以将事件编号作为bash的提示符的一部分显示出来 .
更多的请查看我之前写的Linux 101 Hacks笔记(二)的23)-37)条 .

(一) fc
内置命令fc(fix command)可以用来显示历史列表的内容 .
下面举例分析 :
显示最近的16个命令
$fc -l

显示从事件100到200之间的历史列表
$fc -l 100 200

显示从事件100一直到最后
$fc -l 100

显示以包含vim到包含pwd之间的命令
$fc -l vim pwd

列出某一个事件
$fc -l 100 100

调用vi来编辑最近使用的命令
$fc -e vi

也可以调用emacs来修改 :
$export FCEDIT=/usr/bin/emacs
$fc
这样就可以直接调用emacs了.如果已经设置了FCEDIT变量 , 就没有必要再使用参数-e了 .

开启默认的编辑器 , 并开始编辑事件21
$fc 21

重新执行事件1000
$fc -s 1000

重新执行上一条命令
$fc -s

重新执行第1000个事件 , 并用a替代b
$fc -s b=a 1000

(二) !引用事件
这个我在这里中也提过了 , 再补充几点 :

1) !String : 当在感叹号后面跟着一个文本串时 , shell搜索并执行的是以该文本串开头的事件 . 如果将该文本串用问号括起来 , shell将执行包含该文本串的事件 .
搜索包含apt-get字符串的命令
$ !?apt-get?

2) echo !!:n* : 打印出上一个命令参数中从第n到最后那个之间的所有字.
echo !!:* : 打印出上一个命令除了命令之外的所有参数 , 等同于echo !!:1* .
!$:代表上一个事件的最后一个字.
$cat test
$vi !$

3) 如果一个事件只包含一条命令 , 那么字编号就与参数编号相对应;如果事件包含了多条命令 , 那么对于第1条以后的命令来说 , 这个对应关系就不再成立了 . 举例分析:
先把PS1修改一下:
~ $: PS1="\!:"

272:echo a b c
a b c

273:!272;echo d e f
echo a b c;echo d e f
a b c
d e f

274:echo !273:4
echo ;

275:echo !273:5-7
echo echo d e
echo d e

276:echo !273:6-8
echo d e f
d e f
看到其中的区别了吧~

4) 替换命令行中的错误
$car /etc/passwd (本来是想打cat的)
$!!:s/car/cat
如果是!!:sg/car/cat , 则是将该命令中出现car的地方都替换成cat . 其实就是全局替换 . 或者使用!!:^car^cat^ , 这个和sed中的用法是一致的 .

5) ~ $: ll /var/log/wicd/
total 1004
-rw-r—– 1 root adm 285728 2010-09-17 10:36 wicd.log
-rw-r—– 1 root adm 361710 2010-08-31 23:48 wicd.log.1
-rw-r—– 1 root adm 360879 2010-08-18 15:10 wicd.log.2

~ $: !!:p
ll /var/log/wicd/

~ $: !!:h:p
ll /var/log
加上p的话 , 代表显示命令 , 但是不执行;加上h的话 , 将删除路径的最后一部分 .

(三) Readline库
bash的命令行编辑功能是通过ReadLine库实现的 . 使用ReadLine库的应用程序(包括bash)通过读取~/.inputr获取键绑定信息和配置设置 .
在bash使用ReadLine库的时候 , 用户可以选择两种编辑模式 . 即emacs模式和vi模式 . 默认模式是emacs . 使用如下

命令切换到vi模式 :
$set -o vi
重新切换到emacs模式 :
$set -o emacs
PS:本人一直使用的是vi, 所以接下来会使用vi作为主编辑模式 .

在 vi模式下 , 当输入bash命令时 , 用户处于输入模式 , 如果输入一条命令 , 发现错误 , 可以按Esc切换到vi的命令模式 , 然后就可以像vi的命令模式一样修改了 , 比如x,r,~,等等 , 具体的修改如果熟悉vi的话应该是很简单的一件事 . 想要运行命令 , 不必要回到命令模式 , 直接敲入回车即可 , 光标处于该命令行的中间某个某位置也同样可以执行 .
: 独立版的vim编辑器启动时处于命令模式;命令行vi编辑器 , 启动时处于输入模式 .

在命令行模式下使用?****或者/****表示分别向后和向前搜索包含****的命令 . 与独立版的vim的搜索不同 , 这些搜索串不能包含正则表达式 . 但是可以使用^ , 让shell查找以****开头的命令 . 与在vim中一样 , 在一次成功搜索后 , 可以按n或者N来进行下一次搜索 .

还可以使用时间编号来访问历史 , 当处于命令模式时 , 输入时间编号 , 按下G , 即可跳到该事件编号表示的那条命令 . readline还支持命令补全和路径名补全 , 还包括变量补全 , 这个在编辑模式下有效 .
使用readline库的bash会读取由INPUTRC环境变量指定的文件 , 以获取初始化信息 . 如果没有INPUTRC , 这些程序将从文件~/.inputrc中读取 .

  • http://blog.ibfsu.com Carlos Gong

    终于抢到沙发,内牛满面~

    • http://jaseywang.info jaseywang

      妳也就这么大出息了==