## # 键盘高级操作技巧

I often kiddingly describe Unix as “the operating system for people who like to type.” Of course, the fact that it even has a command line is a testament to that. But command line users don't like to type that much. Why else would so many commands have such short names like cp, ls, mv, and rm? In fact, one of the most cherished goals of the command line is laziness; doing the most work with the fewest number of keystrokes. Another goal is never having to lift your fingers from the keyboard, never reaching for the mouse. In this chapter, we will look at bash features that make keyboard use faster and more efficient.

The following commands will make an appearance:

• clear - Clear the screen

• history - Display the contents of the history list

• clear － 清空屏幕

• history － 显示历史列表内容

### # 命令行编辑

bash uses a library (a shared collection of routines that different programs can use) called Readline to implement command line editing. We have already seen some of this. We know, for example, that the arrow keys move the cursor but there are many more features. Think of these as additional tools that we can employ in our work. It’s not important to learn all of them, but many of them are very useful. Pick and choose as desired.

Bash 使用了一个名为 Readline 的库（共享的例程集合，可以被不同的程序使用）， 来实现命令行编辑。我们已经看到一些例子。我们知道，例如，箭头按键可以移动光标， 此外还有许多特性。想想这些额外的工具，我们可以在工作中使用。学会所有的特性 并不重要，但许多特性非常有帮助。选择自己需要的特性。

Note: Some of the key sequences below (particularly those which use the Alt key) may be intercepted by the GUI for other functions. All of the key sequences should work properly when using a virtual console.

### # 移动光标

The following table lists the keys used to move the cursor:

Table 9-1: Cursor Movement Commands
Key Action
Ctrl-a Move cursor to the beginning of the line.
Ctrl-e Move cursor to the end of the line.
Ctrl-f Move cursor forward one character;same as the right arrow key.
Ctrl-b Move cursor backward one character;same as the left arrow key.
Alt-f Move cursor forward one word.
Alt-b Move cursor backward one word.
Ctrl-l Clear the screen and move the cursor to the top left corner. The clear command does the same thing.

Ctrl-a 移动光标到行首。
Ctrl-e 移动光标到行尾。
Ctrl-f 光标前移一个字符；和右箭头作用一样。
Ctrl-b 光标后移一个字符；和左箭头作用一样。
Alt-f 光标前移一个字。
Alt-b 光标后移一个字。
Ctrl-l 清空屏幕，移动光标到左上角。clear 命令完成同样的工作。

### # 修改文本

Table 9-2 lists keyboard commands that are used to edit characters on the command line.

Table 9-2: Text Editing Commands
Key Action
Ctrl-d Delete the character at the cursor location
Ctrl-t Transpose(exchange)the character at the cursor location with the one preceding it.
Alt-t Transpose the word at the cursor location with the one preceding it.
Alt-l Convert the characters from the cursor location to the end of the word to lowercase.
Alt-u Convert the characters from the cursor location to the end of the word to uppercase.

Ctrl-d 删除光标位置的字符。
Ctrl-t 光标位置的字符和光标前面的字符互换位置。
Alt-t 光标位置的字和其前面的字互换位置。
Alt-l 把从光标位置到字尾的字符转换成小写字母。
Alt-u 把从光标位置到字尾的字符转换成大写字母。

### # 剪切和粘贴文本

The Readline documentation uses the terms killing and yanking to refer to what we would commonly call cutting and pasting. Items that are cut are stored in a buffer called the kill-ring.

Readline 的文档使用术语 killing 和 yanking 来指我们平常所说的剪切和粘贴。 剪切下来的本文被存储在一个叫做剪切环(kill-ring)的缓冲区中。

Table 9-3: Cut And Paste Commands
Key Action
Ctrl-k Kill text from the cursor location to the end of line.
Ctrl-u Kill text from the cursor location to the beginning of the line.
Alt-d Kill text from the cursor location to the end of the current word.
Alt-Backspace Kill text from the cursor location to the beginning of the word. If the cursor is at the beginning of a word, kill the previous word.
Ctrl-y Yank text from the kill-ring and insert it at the cursor location.

Ctrl-k 剪切从光标位置到行尾的文本。
Ctrl-u 剪切从光标位置到行首的文本。
Alt-d 剪切从光标位置到词尾的文本。
Alt-Backspace 剪切从光标位置到词头的文本。如果光标在一个单词的开头，剪切前一个单词。
Ctrl-y 把剪切环中的文本粘贴到光标位置。

The Meta Key

If you venture into the Readline documentation, which can be found in the READLINE section of the bash man page, you will encounter the term “meta key.” On modern keyboards this maps to the Alt key but it wasn't always so.

Back in the dim times (before PCs but after Unix) not everybody had their own computer. What they might have had was a device called a terminal. A terminal was a communication device that featured a text display screen and a keyboard and just enough electronics inside to display text characters and move the cursor around. It was attached (usually by serial cable) to a larger computer or the communication network of a larger computer. There were many different brands of terminals and they all had different keyboards and display feature sets. Since they all tended to at least understand ASCII, software developers wanting portable applications wrote to the lowest common denominator. Unix systems have a very elaborate way of dealing with terminals and their different display features. Since the developers of Readline could not be sure of the presence of a dedicated extra control key, they invented one and called it “meta.” While the Alt key serves as the meta key on modern keyboards, you can also press and release the Esc key to get the same effect as holding down the Alt key if you're still using a terminal (which you can still do in Linux!).

### # 自动补全

Another way that the shell can help you is through a mechanism called completion. Completion occurs when you press the tab key while typing a command. Let's see how this works. Given a home directory that looks like this:

shell 能帮助你的另一种方式是通过一种叫做自动补全的机制。当你敲入一个命令时， 按下 tab 键，自动补全就会发生。让我们看一下这是怎样工作的。给出一个看起来 像这样的家目录：

[me@linuxbox ~]$ls Desktop ls-output.txt Pictures Templates Videos ....  Try typing the following but don't press the Enter key: 试着输入下面的命令，但不要按下 Enter 键： [me@linuxbox ~]$ ls l


Now press the tab key:

[me@linuxbox ~]$ls ls-output.txt  See how the shell completed the line for you? Let's try another one. Again, don't press Enter: 看一下 shell 是怎样补全这一行的？让我们再试试另一个例子。这回，也 不要按下 Enter: [me@linuxbox ~]$ ls D


Press tab:

[me@linuxbox ~]$ls D  No completion, just a beep. This happened because “D” matches more than one entry in the directory. For completion to be successful, the “clue” you give it has to be unambiguous. If we go further: 没有补全，只是嘟嘟响。因为"D"不止匹配目录中的一个条目。为了自动补全执行成功， 你给它的"线索"不能模棱两可。如果我们继续输入： [me@linuxbox ~]$ ls Do


Then press tab:

[me@linuxbox ~]$ls Documents  The completion is successful. 自动补全成功了。 While this example shows completion of pathnames, which is its most common use, completion will also work on variables (if the beginning of the word is a “$”), user names (if the word begins with “~”), commands (if the word is the first word on the line.) and host names (if the beginning of the word is “@”). Host name completion only works for host names listed in /etc/hosts.



By default, bash stores the last five hundred commands you have entered. We will see how to adjust this value in a later chapter. Let's say we want to find the commands we used to list /usr/bin. One way we could do this:

[me@linuxbox ~]$history | grep /usr/bin  And let's say that among our results we got a line containing an interesting command like this: 比方说在我们的搜索结果之中，我们得到一行，包含了有趣的命令，像这样； 88 ls -l /usr/bin > ls-output.txt  The number “88” is the line number of the command in the history list. We could use this immediately using another type of expansion called history expansion. To use our discovered line we could do this: 数字 "88" 是这个命令在历史列表中的行号。我们可以使用另一种叫做 历史命令展开的方式，来调用“88”所代表的这一行命令： [me@linuxbox ~]$ !88


bash will expand “!88” into the contents of the eighty-eighth line in the history list. There are other forms of history expansion that we will cover a little later. bash also provides the ability to search the history list incrementally. This means that we can tell bash to search the history list as we enter characters, with each additional character further refining our search. To start incremental search type Ctrl-r followed by the text you are looking for. When you find it, you can either type Enter to execute the command or type Ctrl-j to copy the line from the history list to the current command line. To find the next occurrence of the text (moving “up” the history list), type Ctrl-r again. To quit searching, type either Ctrl-g or Ctrl-c. Here we see it in action:

bash 会把 "!88" 展开成为历史列表中88行的内容。还有其它的历史命令展开形式，我们一会儿 讨论它们。bash 也具有按递增顺序来搜索历史列表的能力。这意味着随着字符的输入，我们 可以告诉 bash 去搜索历史列表，每一个附加字符都进一步提炼我们的搜索。启动递增搜索， 输入 Ctrl-r，其后输入你要寻找的文本。当你找到它以后，你可以敲入 Enter 来执行命令， 或者输入 Ctrl-j，从历史列表中复制这一行到当前命令行。再次输入 Ctrl-r，来找到下一个 匹配项（向上移动历史列表）。输入 Ctrl-g 或者 Ctrl-c，退出搜索。实际来体验一下：

[me@linuxbox ~]$ First type Ctrl-r: 首先输入 Ctrl-r: (reverse-i-search)':  The prompt changes to indicate that we are performing a reverse incremental search. It is “reverse” because we are searching from “now” to some time in the past. Next, we start typing our search text. In this example “/usr/bin”: 提示符改变，显示我们正在执行反向递增搜索。搜索过程是"反向的"，因为我们按照从"现在"到过去 某个时间段的顺序来搜寻。下一步，我们开始输入要查找的文本。在这个例子里是 "/usr/bin"： (reverse-i-search)/usr/bin': ls -l /usr/bin > ls-output.txt  Immediately, the search returns our result. With our result, we can execute the command by pressing Enter, or we can copy the command to our current command line for further editing by typing Ctrl-j. Let's copy it. Type Ctrl-j: 即刻，搜索返回我们需要的结果。我们可以按下 Enter 键来执行这个命令，或者我们可以按下Ctrl-j复制 这个命令到我们当前的命令行，来进一步编辑它。好了现在我们复制它，输入 Ctrl-j： [me@linuxbox ~]$ ls -l /usr/bin > ls-output.txt


Our shell prompt returns and our command line is loaded and ready for action! The table below lists some of the keystrokes used to manipulate the history list:

Table 9-5: History Commands
Key Action
Ctrl-p Move to the previous history entry. Same action as the up arrow.
Ctrl-n Move to the next history entry. Same action as the down arrow.
Alt-< Move to the beginning (top) of the history list.
Alt-> Move to the end (bottom) of the history list, i.e., the current command line.
Ctrl-r Reverse incremental search. Searches incrementally from the current command line up the history list.
Alt-p Reverse search, non-incremental. With this key, type in the search string and press enter before the search is performed.
Alt-n Forward search, non-incremental.
Ctrl-o Execute the current item in the history list and advance to the next one. This is handy if you are trying to re-execute a sequence of commands in the history list.

Ctrl-p 移动到上一个历史条目。类似于上箭头按键。
Ctrl-n 移动到下一个历史条目。类似于下箭头按键。
Alt-< 移动到历史列表开头。
Alt-> 移动到历史列表结尾，即当前命令行。
Ctrl-r 反向递增搜索。从当前命令行开始，向上递增搜索。
Alt-p 反向搜索，不是递增顺序。输入要查找的字符串，然后按下 Enter，执行搜索。
Alt-n 向前搜索，非递增顺序。
Ctrl-o 执行历史列表中的当前项，并移到下一个。如果你想要执行历史列表中一系列的命令，这很方便。

### # 历史命令展开

The shell offers a specialized type of expansion for items in the history list by using the “!” character. We have already seen how the exclamation point can be followed by a number to insert an entry from the history list. There are a number of other expansion features:

Table 9-6: History Expansion Commands
Sequence Action
!! Repeat the last command. It is probably easier to press up arrow and enter.
!number Repeat history list item number.
!string Repeat last history list item starting with string.
!?string Repeat last history list item containing string.

!! 重复最后一次执行的命令。可能按下上箭头按键和 enter 键更容易些。
!number 重复历史列表中第 number 行的命令。
!string 重复最近历史列表中，以这个字符串开头的命令。
!?string 重复最近历史列表中，包含这个字符串的命令。

I would caution against using the “!string” and “!?string” forms unless you are absolutely sure of the contents of the history list items.

There are many more elements available in the history expansion mechanism, but this subject is already too arcane and our heads may explode if we continue. The HISTORY EXPANSION section of the bash man page goes into all the gory details. Feel free to explore!

script

In addition to the command history feature in bash, most Linux distributions include a program called script that can be used to record an entire shell session and store it in a file. The basic syntax of the command is:

script [file]

where file is the name of the file used for storing the recording. If no file is specified, the file typescript is used. See the script man page for a complete list of the program’s options and features.

### # 总结归纳

In this chapter we have covered some of the keyboard tricks that the shell provides to help hardcore typists reduce their workloads. I suspect that as time goes by and you become more involved with the command line, you will refer back to this chapter to pick up more of these tricks. For now, consider them optional and potentially helpful.