第08章:高级键盘技巧

我经常打趣地描述 Unix 为「为那些喜欢打字的人提供的操作系统」。当然,甚至有一个命令行证明了这一点。但是命令行用户不喜欢打很多命令。为何这么多命令的名字都是这么短呢,像 cplsmvrm 之类?事实上,众多命令行所珍视的目标中的一个,就是懒惰。用最少的击键次数,来做最多的工作。另一个目标是永远都不要把我们的手指从键盘挪开到鼠标。本章中,我们将看到 bash 能让键盘更快且更高效的几个特征。

下列命令将会露脸:

  • clear 清理屏幕

  • history 显示历史清单

编辑命令行

bash 使用一个名为 Readline 的库(一个供不同程序使用的共享路径集合)来执行命令行编辑。我们已经学习了一些。我们知道,例如箭头键可以移动光标,但还有更多特性。想像成我们可以在工作中采用的附加工具。完整地学习并不重要,但是确实非常有用。要按需选用。

注意:下面一些键序(特别是那些用了 Alt 键的)在图形界面中可能被解释成其它功能。所有这些键序能在虚拟终端中正常工作。

光标移动

下表中的键用来移动光标:

表 8-1:光标移动命令

行为

Ctrl-a

移动光标到行首

Ctrl-e

移动光标到行尾

Ctrl-f

向前移动一个字符,与右箭头作用相同

Ctrl-b

向后移动一个字符,与左箭头作用相同

Alt-f

向前移动一个单词

Alt-b

向后移动一个单词

Ctrl-l

清理屏幕,并移动光标到左上角。作用与 clear

编辑文本

因为我们在编写一个命令时可能会出错,所以需要有高效地办法来改正。表 8-2 描述了用来编辑命令行字符的键盘命令。

表 8-2 文本编辑命令

行为

Ctrl-d

删除光标处的字符。

Ctrl-t

颠倒(交换)光标位置与其之前的一个字符。

Alt-t

颠倒(交换)光标位置与其之前的一个单词。

Alt-l

将光标当前位置到单词结束位置的字符转换为小写。

Alt-u

将光标当前位置到单词结束位置的字符转换为大写。

剪切与粘贴文本

读行文档采用杀戮和劫持(killing and yanking)来称呼我们日常所说的剪切和粘贴(cutting and pasting)。被剪切的项目存储在一个缓冲区(buffer 内存中的临时存储区域)中,被称为杀环(kill-ring)。

表 8-3 剪切与粘贴命令

行为

Ctrl-k

杀掉从光标位置到行尾的字符。

Ctrl-u

杀掉从光标位置到行首的字符。

Alt-d

杀掉从光标位置到当前单词的结尾位置。

Alt-Backspace

杀掉从光标位置到当前单词的开头位置。如果光标在一个单词的开始位置,就删掉之前的一个单词。

Ctrl-y

从杀环劫持文本,插入当前光标位置。

元键(The Meta Key)

如果你冒险进入阅读文档,就是那个在 bash 手册页中的一个章节,你将遇到一个术语:元键(meta key),在现代键盘中,映射到 Alt 键,不过也并不总是如此。

回到那段黯淡时光(Unix 之后,PC 之前),不是所有人都有他们自己的电脑。他们可能用到的设备,叫终端(terminal)。终端是一个通讯设备,具有一个文本显示屏和一个键盘,仅仅有一些电器元件以显示文本字符,移动光标。它通常用串行电缆(serial cable)连接到更大的计算机或者是更大的计算机通讯网络。会有许多不同品牌的终端,它们也各自有不同的键盘和显示设备。由于它们都倾向于起码要理解 ASCII,软件开发者希望可移植的应用程序有个最低的共同点。Unix 系统有一个精心设计的用以处理终端和不同显示特性的方案。由于读行的开发人员无法确定是否存在专用的额外控制键,因此他们发明了一个,并称之为元键。在现代键盘中,Alt 键用来做元键,当然你如果仍旧在使用终端,也可以按下并释放 Esc 键,来达到和按住 Alt 键一样的效果,在 Linux 中,这招也有效。

补全命令

Shell 还有一个可以帮到我们的机制,叫做补全(completion)。在我们输入命令时,我们按 Tab 键,可以实现补全。我们来看一下是如何工作的。像这样给出一个家目录:

[me@linuxbox ~]$ ls
Desktop Documents ls-output.txt Music Public Pictures Templates Videos

试着输入下面这几个字符,但不要按 Enter

[me@linuxbox ~]$ ls l

现在按 Tab 键:

[me@linuxbox ~]$ ls ls-output.txt

看到 shell 如何帮我们完成这一行了吗?试试另外一个,也不要按 Enter

[me@linuxbox ~]$ ls D

Tab 键。

[me@linuxbox ~]$ ls D

没有补全,什么也没有。因为 D 匹配着目录中多于一个的条目。为了成功补全,我们所给出的「线索」,必须是没有歧义的。如果我们输入的多一点,如下:

[me@linuxbox ~]$ ls Do

然后按 Tab 键:

[me@linuxbox ~]$ ls Documents

成功补全。

上例中显示了补全路径,是它最常用的一个功能,补全功能也可以工作在变量(以 $ 开头的单词),用户名(以 ~ 开头的单词),命令(在行首出现的单词)和主机名(以 @ 开头的单词。主机名补全功能仅为 /etc/hosts 文件中的主机名列表工作。

有一些控制和元键组合键与补全关联,见表 8-4。

表 8-4 补全命令

行为

Alt-?

显示一个可能补全的列表。在大多数系统中,你可以更简单地按住 Tab 键一秒钟来实现这个功能。

Alt-*

插入所有可能的补全。当想要用多过一个可能的匹配时,会很有用。

还有一些相当模糊的东西。在 bash 的手册页 "READLINE" 下,有一个列表。

可编程的补全

晚近版本的 bash 有个设施叫做可编程补全(programmable completion)。可编程补全允许你(或更接近地说,你的发行版提供者)添加附加的补全规则。通常为特别的应用程序增加支持。例如,为一个命令的选项列表或匹配应用程序所支持的特殊类型的文件。Ubuntu 有大量默认定义的集合。可编程补全由 shell 提供的一种迷你的 shell 脚本来实现,后续章节将会继续介绍。如果你好奇,就试试这个:

set | less

不是所有的发行版都默认包含这些。

使用历史

如第一章中所揭示,bash 维护着一个已经输入过的命令的历史记录。这个列表保存在我们的家目录中,文件名为 .bash_history。历史命令设施是个很有用的资源,能减少大量的输入工作,特别是在命令行编辑过程中。

搜索历史

任何时候,我们能这样查看历史列表:

[me@linuxbox ~]$ history | less

缺省情况下,bash 保存我们所输入的最近 500 条命令,大部分现代发行版会将这个数字设置为 1,000 条。在第 11 章,我们会看到如何调整这个数值。现在我们要找出曾经用过的列出 /usr/bin 目录的命令,可以这么做:

[me@linuxbox ~]$ history | grep /usr/bin

在结果中,我们找到一行有意思的命令:

88 ls -l /usr/bin > ls-output.txt

88 是这个命令在历史列表中的行号。我们可以用一种叫历史扩展(history expansion)的方法来使用它。要用到我们发现的行号,这样做:

[me@linuxbox ~]$ !88

bash 会扩展 !88 到历史列表中的第 88 行。下节中我们将看到历史扩展的另一种形式。

bash 还提供增量搜索历史列表的能力。意味着在我们每键入一个字符时,我们能让 bash 去提炼搜索历史列表。要开启增量搜索,按下 Ctrl-r,随后键入我们要查找的文本。当我们找到后,按 Enter 执行命令或者按 Ctrl-j 从历史列表中复制到当前命令行。要找到文本的下一次出现(向「上」移动历史列表),再次按下 Ctrl-r。要退出检索,请按 Ctrl-gCtrl-c。现在来看一下:

[me@linuxbox ~]$

首先,按下 Ctrl-r

(reverse-i-search)`':

提示符改变了,提示我们正在执行反向增量检索(reverse incremental search),这里的「反向」指我们正在从「现在」开始到过去的某个时间。然后,我们键入要检索的文本,如 /usr/bin

(reverse-i-search)`/usr/bin': ls -l /usr/bin > ls-output.txt

检索即时地返回了结果。在结果中,我们按 Enter 以执行命令,或者按 Ctrl-j 将命令复制到当前命令行供再次修改。让我们复制吧,按下 Ctrl-j

[me@linuxbox ~]$ ls -l /usr/bin > ls-output.txt

提示符返回到先前状态,命令已经装载好,等待行动。

表 8-5 列出了一些键盘快捷键,用来修改历史列表。

表 8-5 历史命令

行为

Ctrl-p

移动到上一条命令。与向上箭头键功能相同。

Ctrl-n

移动到下一条命令。与向下箭头键功能相同。

Alt-<

移动到历史列表的开始位置(顶端)。

Alt->

移动到历史列表的结束位置(底端),即当前命令行。

Ctrl-r

反向增量检索。从当前命令行向上搜索历史列表。

Alt-p

反向检索,没有增量。用这个按键,输入检索字符串,按 Enter 执行检索。

Alt-n

向前检索,没有增量。

Ctrl-o

执行历史列表中的当前项目并向前进到下一个项目。 如果我们尝试在历史列表中重新执行一系列命令,这很方便。

历史扩展

Shell 用 ! 字符为历史列表中的条目提供一种特别的扩展。我们已经看到感叹号后跟着一个历史列表的条目数字。还有一些其它类型的扩展,如表 8-6。

表 8-6 历史扩展命令

序列

行为

!!

重复上次命令,这可能比按向上箭头键再按 Enter 方便。

!数字

重复数字所示的历史命令条目。

!文本

重复以文本开头的历史命令条目。

!?文本

重复包含文本的历史命令条目。

我要警告一下,除非你确信历史列表条目的内容,否则不要使用 !文本!?文本

还有很多可用的历史扩展机制,但是这个主题过于神秘,如果继续下去,估计脑袋要爆炸了。bash 手册页中的 HISTORY EXPANSION 章节会进入各个精彩的细节。自由地去探索吧!

脚本 script

现代 Linux 发行版的 bash,在提供历史命令的特性之外,还提供一个叫 script 的程序,记录整个 shell 的会话并保存到一个文件中。基本命令句法如下:

script [file]

file 是用来存储记录的文件名。如果没有指定文件名,就用 typescript 作为文件名。请查看 script 的手册页来看程序的选项和特性。

总结

本章中我们学习了由 shell 提供的一些键盘技巧来帮助键盘侠们减少工作量。随着更深地涉入命令行,我们可以回到本章,学习这些技巧。现在,将它们视为可选的,且潜在有帮助的功能。

扩展阅读

Last updated

Was this helpful?