3.6 快速执行历史命令

既然我们把已经执行过的命令存储到 Shell 的历史文件中,那么自然想有一天能够再次用到它。正所谓“养兵千日,用兵一时”。下面,我们就来看一看如何快速的执行已有的历史命令。

3.6.1 重复执行上一条命令

一种常见的使用场景是,我在使用 htop 查看系统状态并退出后,过一会儿想再次查看它。此时,我们无需重新输入 htop 命令,只需按两下 !! 并敲回车即可。

xiaodong@codeland:~$ htop
xiaodong@codeland:~$ !!

!! 被称为 bang bang,是我最喜欢使用,同时也是使用频率极高的历史命令调用表示。!! 让我们以最快的方式重复执行上一条命令。

!! 经常与 sudo 联用,用来解决缺少权限的问题。例如:

xiaodong@codeland:~$ pacman -S figlet
error: you cannot perform this operation unless you are root.

在此,我用 pacman 来安装 figlet,但由于是普通账户,所以没有权限操作。要解决这个问题,我们只要输入:

xiaodong@codeland:~$ sudo !!
xiaodong@codeland:~$ sudo pacman -S figlet

3.6.2 执行以某些字符打头的命令

利用 !foo 这种表示法允许我们执行以 foo 这三个字符打头的命令。Shell 将以逆序的方式搜索历史命令列表,一旦与给定的开头字符匹配到,便予以执行该条命令。例如:

xiaodong@codeland:~$ !he
xiaodong@codeland:~$ help

该表示从历史命令列表中找到 help 后执行。

3.6.3 执行历史列表中第 n 个命令

! 后面除了可以跟一个字符串之外,也可以跟一个数字。这个数字代表历史命令列表中的编号。当我们用 history 查看历史命令列表时,命令左边显示的即是该行命令的编号。例如:

xiaodong@codeland:~$ history 5

这里显示 htop 的编号为 52,如图 3.2 所示。

history 5 执行结果

图 3.2: history 5 执行结果

所以我们可以用:

xiaodong@codeland:~$ !52

来再次执行 htop

利用 !-2,我经常使用的一个场景是,先用文本编辑器编辑源代码,接着再编译源代码。如果我需要再次编辑和编译,那么只要反复执行 !-2 即可。如此不断循环。

xiaodong@codeland:~$ nvim first.c
xiaodong@codeland:~$ gcc -o first first.c
xiaodong@codeland:~$ !-2 # 再编辑
xiaodong@codeland:~$ !-2 # 再编译

顺便说一句,因为 !-1 是如此常见,所以 Shell 提供了简写形式 !!