一、命令历史介绍
bash以及其他大多数shell(如korn shell、tc shell 、c shell和z shell等)均支持命令历史机制,以便维护用户输入的命令。shell的命令历史机制和编辑功能是用户能够重复利用先前输入的命令,提高用户的交互访问能力。利用shell的命令历史机制,能够不加修改的重复执行先前提交的任何命令,或者在先前命令的基础上经过校正命令中的细小打字错误或稍加编辑后组成一个新的命令,然后在重复执行先前的命令。
命令历史机制主要是由shell提供的下列内部命令和环境变量时间的。
fc:用于列出(-l 选项)、编辑(-e 选项)或重新执行命令历史文件中记录的命令。
history:用于列出命令历史缓冲区或文件中记录的命令。
HISTFILE:用指定命令历史文件。使用shell能够在停止运行之前把缓冲区中的命令历史记录写入到指定文件,以便在下一次启动时shell能够读回其中保存的、上一次会话期间执行的命令历史记录。如果HISTFILE变量没有被定义,或者定义的文件没有“可写”的访问权限,默认的命令历史文件为$HOME/.bash_history。
HISTSIZE:指定命令历史文件的大小,用于限定当前会话期间需要保存在命令历史文件中命令数量。如果HISTSIZE变量没有被定义,则文件容量的默认值为500,即保存最近执行的500条命令。
HISTFILESIZE:指定命令历史文件的大小。用于限定不同会话之间需要保存到命令历史文件中命令数量。如果HISTFILESIZE变量没有被定义,则文件容量的默认值为500,即保存最近执行的500条命令。
HISTCONTROL:控制命令历史的生成
ignoredups:忽略记录重复的命令;连续的相同命令才为重复(默认值)。
ignorespace:不记录以空白字符串开头的命令
ignoreboth:同时具有上面两种特性
二、fc命令
1. 命令所在路径:shell内置命令
2.执行权限:所有用户
3. 命令格式:
fc [-e ename] [-nlr] [first [last]]
fc -s [old=new] [command]
4. 功能描述
利用特殊的内置命令fc,可以按照命令序号或利用命令的起始字符(或字符串)显示、编辑或运行先前执行的命令。在使用fc命令列举命令历史缓冲区或文件中的命令时,可以指定单个命令,也可以指定一个命令范围。
5. 第一种格式选项与参数说明
-e ename:使用指定编辑器ename编辑选定的命令,和-l选项配合时则将命令列举在标准输出上。
-n:使得列举时不显示命令号码。
-r:将命令的顺序进行调换
-l:将命令列举在标准输出上
命令参数:first和last可以是指定为字符串(可以是最后一个以此字符串开始的命令)或者数据(历史列表中的索引,负数被当作当前命令号的偏移)。如果没有指定last,它在列举时设为当前命令将输出最后10条命令,其他情况被设定为first。如果没有指定first,他在编辑时被设为前一个命令,列举设为16
6.第二种格式选项与参数说明:
-s:跳过编辑阶段,如果存在old=new形式的字符串,则由shell直接执行命令替换,然后重新指向编辑后的新命令,如果未给出命令,则表示执行之间刚执行过的命令。
7.范例:
# 编辑刚刚执行过的命令,当退出编辑器是会重新执行
[root@centos6 ~]# fc
#显示命令历史序号10到20之间的命令
[root@centos6 ~]# fc -l 10 20
10 ls
11 vi ifcfg-eth0
12 ifconfig eth0 up
13 ifconfig
14 ifconfig eth0 192.168.0.89
15 ifconfig
16 ping 192.168.0.1
17 service network start
18 ls
19 ifconfig
20 ping baidu.com
#编辑10到12之间的命令,退出编辑器时会依次执行所选命令
[root@centos6 ~]# fc 10 12
#使用vi编辑编辑10到12之间的命令
[root@centos6 ~]# fc -e vi 10 12
#使用倒序排列最近执行的10条命令
[root@centos6 ~]# fc -lr -10
230 fc -l 10 20
229 capsh cd
228 info cd
227 type cd
226 type tyep
225 whereis type
224 cal
223 man date
222 date
221 history -w
#不看命令编号倒序查看最近执行的两条命令
[root@centos6 ~]# fc -lrn -2
fc -lr -10
fc -l 10 20
#列出最近一次执行以man开头的命令直到当前命令(编辑模式只有最后执行以man开头的命令)
[root@centos6 ~]# fc -l man
223 man date
224 cal
225 whereis type
226 type tyep
227 type cd
228 info cd
#查看date的帮助文档
[root@centos6 ~]# man date
#替换man date中的date为cal并执行
[root@centos6 ~]# fc -s date=cal
man cal
#执行命令序号499的命令
[root@centos6 ~]# fc -s 499
man cal
三、history命令
1. 命令所在路径:shell内置命令
2. 执行权限:所有用户
3. 命令格式
history [n]
history -c
history -d offset
history -anrw [filename]
history -p arg [arg ...]
history -s arg [arg ...]
4. 功能描述
内置命令是fc命令的一个特例(在Korn Shell中,history只是利用fc命令定义的一个命令别名,即alias history="fc -l"),用于读取、显示或清除命令记录中的命令。例如为了列出命令历史缓冲区或文件中记录的命令。
5. 选项说明
不带选项的话,显示带行号的命令历史列表(在bash中通常会列出命令历史缓冲区或文件中的所有命令,而在Korn shellzhong 仅列出16条命令);
参数n表示显示最后n行。
参数filename表示被用作历史文件名,默认将使用HISTFILE的值作为历史文件。
-c 清空历史列表,删除所有条目。
-d offset 删除offset位置的历史条目
-a 将新的历史条目(自当前bash会话开始输入的历史命令)追加到历史文件中。
-n 将尚未从历史文件中读取的历史条目读入当前历史列表。这些行是当前bash会话开始之后,才追加到历史文件的行中。
-r 读取历史文件的内容,使用他们作为当前历史。
-w 将当前历史列表写入历史文件中,覆盖历史文件的原有内容
-p 对后续的args进行历史替换,在标准输出上显示结果。不会将结果存入历史列表中,每个args都必须被引用,来禁止普通的命令扩展。
-s 将arg保存到历史列表中,做为单独的条目。历史列表中的最后一个命令在添加args之前被删除。
6. 范例
#显示所有历史命令
[root@centos6 ~]# history
#显示最近执行的10命令
[root@centos6 ~]# history 10
#保存当前历史列表到HISTFILE文件中
[root@centos6 ~]# history -w
#保存当前历史列表到.root.history文件中
[root@centos6 ~]# history -w .root.history
#清空当前历史列表
[root@centos6 ~]# history -c
#清空HISTFILE文件中的历史记录
[root@centos6 ~]# history -w
#读取HISTFILE文件中的历史记录
[root@centos6 ~]# history -n
#显示最近执行的10条命令,因为之前清空了现在只有刚刚执行的3个命令
[root@centos6 ~]# history 10
1 history -w
2 history -n
3 history 10
#读取.root.history文件中的命令历史列表
[root@centos6 ~]# history -n .root.history
#显示最近执行的10条命令(还原之前的历史记录了)
[root@centos6 ~]# history 10
521 cat a.sh
522 cat install.log
523 ls
524 rm -rf anaconda-ks.cfg cheat ls a.sh
525 ls
526 rm -rf manpages-zh-1.5.1
527 ls
528 history -w
529 history -w .root.history
530 history 10
四、history重复执行先前的命令
在bash中为了重复执行先前的命令,可以利用感叹号!引用机制实现。感叹号!代表引用命令历史缓冲区或文件中的命令。若要不加修改的执行最近刚执行的命令,可以使用!!命令。
!string命令表示重新执行最近执行的且以string为起始字符的命令。而!?string?则表示重新执行最近运行的切中包含给定字符串的命令,因此如果输入!gcc命令将会重新执行最近输入的以gcc为起始字符串的命令。
!n表示重新执行命令历史缓冲区或文件中的n号命令,而!-n则表示重新执行最近执行行的倒数第n号命令。
利用!!:[g]s/old/new[/]命令还可以修正刚执行的命令,然后在执行。即使执行之前先以给定的字符串new替换先前命令中第一个出现的字符串old,然后再执行校正后的新命令,如果命令行中存在多个匹配字符串,需要全部替换,可以在s之前增加一个字符g表示替换所有匹配的字符串,另外最后一个斜线字符可以省略。
在Korn Shell中可以利用命令别名r重复执行先前输入的最近一个命令,如果仅仅输入一个r字符则意味着重复执行最近刚执行的命令。为在bash中使用korn shell用户已经习惯的r命令,可以利用fc命令定义以个命令别名,然后可使用r命令。alias r='fc -s'或alias r='fc -e -'。
命令 简单说明
! 表示引用命令缓冲区或文件中的命令(除非后面紧跟着空格、换行符、符号=或左圆括号等字符)
!! 重复执行先前刚执行的命令,相当于输入!-1命令
!N 重复执行命令历史缓冲区或文件中序号为N的命令
!-N 重复执行从当前命令位置开始倒计数的第N个命令
!string 重复执行最近一次执行的以给定字符string为起始字符串的命令
!?string? 重复执行最近一次执行的并且包含给定字符串string字符的命令
!!string 引用前一个命令,附加给定的字符串string然后重新执行组合后的命令
!Nstring 引用第N个命令,附加给定的字符串string然后重新执行组合后的命令
!-Nstring 引用最近执行倒数的第N的命令附加给定的字符串string然后重新执行组合后的命令
!# 引用迄今为止已经输入的所有字符串(当前命令行中尚未执行的字符串)
!$ 引用前一个命令的最后一个参数
!-N$ 引用倒数第N个命令的最后一个参数
!!:[g]s/old/new[/] 重复执行先前的命令,在执行之前,先以给定的字符串new替换命令中出现的第一个或全部(如果s前有一个g字符)字符串old,最后一个斜杠可以省略
^old^new^ 重复执行先前的命令(快速替换形式)。在执行之前以给定字符串new替换命令中的第一个出现的old
以上知识列出最长用的一些快捷模式,很多模式之前还能组合出更多中不同效果,例如:!N$引用前命令历史缓冲区中的序号为N的命令的最后一个参数。
实例:
#显示一个日历
[root@centos6 ~]# cal 09 2014
九月 2014
日 一 二 三 四 五 六
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
#重复执行刚刚执行过的命令
[root@centos6 ~]# !!
cal 09 2014
九月 2014
日 一 二 三 四 五 六
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
#和!!效果一样执行前一个命令
[root@centos6 ~]# !-1
cal 09 2014
九月 2014
日 一 二 三 四 五 六
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
#查看根目录
[root@centos6 ~]# ls /
bin ……
#切换到根目录(引用前一次执行命令的最后一个参数)
[root@centos6 ~]# cd !$
cd /
#切换到root目录(引用前一个命令并追加root之后执行)
[root@centos6 /]# !!root
cd /root
#替换前一个命令中的root为etc并执行
[root@centos6 ~]# ^root^etc^
cd /etc
#替换前一次执行的命令中的etc为root并执行
[root@centos6 etc]# !!:s/etc/root
cd /root
五、编辑并执行校正后的命令
在bash中用户可以利用shell提供的命令历史机制和命令行编辑功能,是用熟悉的编辑器如vi或vim或emacs等对先前输入的命令进行编辑从而生成新的命令,然后提交shell执行。在调用bash是如果使用了--noediting选项,将会关闭命令行编辑功能。
进入bash之后shell将安装FCEDIT和EDITOR变量的值作为命令行编辑器,如果为设置EDITOR便令emacs将成为默认的命令行编辑器,在emacs编辑模式下命令行总是处于输入模式,可以利用上下箭头健翻阅之前输入的命令,这些命令存储在用户主目录下的.bash.history文件或有HISTFILE变量指定的命令历史文件中。利用左右箭头建可左右移动光标插入任何字符,或使用退格键删除光标左边的字符,使用delete健可以删除光标所在位置的字符,编辑命令行。要使用vi或vim编辑命令行,可以采用FCEDIT=vi;export FCEDIT或EDITOR=vi;export EDITOR;另外可以是用set命令设置默认的编辑器如:set -o vi。一旦采取上述措施之一,既可以进入vi命令行编辑模式。命令提示符所在行(通常是终端差un港口底部的最后一行)就像一个只有一行数据的编辑窗口。
无论何时,只要按下esc键即可进入vi命令模式,当处于vi命令模式时,可以使用上下箭头翻阅之前输入的命令,或者使用-或+(j或k键)上下移动命令历史记录,翻阅期望运行的命令,也可以使用/、?或G等vi命令前后检索命令,使用左(或空格)右箭头移动光变,可使用编辑命令校正命令行,如使用x删除单个字符,r替换单个字符,R替换字符,是用I(或I)插入字符或字符串,使用a(或A)附加字符串等等。
完成命令编辑之后,按下enter键即可执行校正后的命令。与vi编辑模式相比emacs编辑模式使用更容易,下面列出常用命令行编辑命令。
Vi(命令模式) | Emacs | 简单说明 |
---|
上箭头,减号-或k | 上箭头或ctrl+P | 获取前一个命令 |
下箭头、加号+或j | 下箭头或ctrl+N | 获取下一个命令 |
左箭头、ctrl+H或h | 左箭头或ctrl+B | 左移一个字符位置 |
右箭头、空格或l | 右箭头或ctrl+F | 右移一个字符位置 |
B | Esc
B | 左移一个字 |
w | Esc F | 右移一个字 |
退格键(编辑模式) | 退格键 | 删除光标位置左边的一个字符 |
X | Delete或ctrl+D | 删除光标所在位置的一个字符 |