在Bash中高效地使用历史记录
1. 概述
每当我们在任何 Linux 终端上工作时,我们通常都会使用 Bash shell。我们使用不同的选项多次键入许多常用命令。有时在输入冗长的命令时,我们意识到有一些错误。我们不是重新输入整个文本,而是使用丰富的历史特征来纠正和搜索。
在本教程中,我们将了解 如何使用 Bash 历史记录来更有效地工作。
2. 启用历史记录的基本配置
为了让 Bash shell 允许历史操作,我们首先需要 启用 history 。我们还需要配置 Readline 库 以从命令行读取输入。在本节中,我们将讨论如何启用历史记录和配置 Readline 库。
当 Bash shell 启动时,它会初始化历史记录并读取 .inputrc 文件以获取 Readline 库配置。
2.1.启用 Bash 历史记录
首先,让我们检查是否启用了历史记录:
$ set -o | grep history
history on
如果历史记录被关闭,我们将通过在 .bashrc 文件中设置来打开它:
$ set -o history
之后,让我们使用*echo * 命令查看是否设置了文件位置和历史记录大小 。HISTFILE 变量存储历史文件的位置:
$ echo $HISTFILE
如果值为 /dev/null,那么一如既往,我们需要在 .bashrc 文件中进行设置:
HISTFILE=$HOME/.bash_history
我们使用 HISTSIZE 和 HISTFILESIZE 变量来配置 Bash 历史的长度:
$ echo $HISTSIZE
$ echo $HISTFILESIZE
如果 HISTSIZE 或 HISTFILESIZE 的值为零,我们需要在 .bashrc 文件中配置它们:
HISTFILESIZE=500
HISTSIZE=500
2.2. 配置 Readline 库
现在,我们将配置 Readline 库。为此,我们需要使用 .inputrc 文件。.inputrc文件描述了 键绑定、变量赋值和条件语法。 我们可以通过自定义主目录中的.inputrc文件来覆盖 Readline 库 的默认行为。
要将编辑器从 emacs (默认模式)更改为 vi:
$ set editing-mode vi
设置可见铃:
$ set bell-style visible
如果我们想忽略这种情况:
$ set completion-ignore-case On
设置好变量后,让我们继续为遍历配置键。
对于 ANSI 模式,我们将箭头键设置为:
"\M-[D": backward-char
"\M-[C": forward-char
"\M-[A": previous-history
"\M-[B": next-history
我们可以通过在*.bashrc* 文件:
$ bind '"\e[A": history-search-backward'
$ bind '"\e[B": history-search-forward'
这里, \M- 是元键。如果元键不存在,则表示转义键,即 \e。
3. 使用 Bash 历史
现在 shell 已经配置好了,让我们开始使用历史。首先,我们将了解如何搜索现有的历史文件。然后,我们将学习如何使用 Bash 提供的内置命令。最后,我们将看到如何修改和执行命令。
3.1. 穿越历史
我们使用箭头键或控制键来遍历历史:
- ⬆️ 或 CTRL-p:向后遍历
- ⬇️ 或 CTRL-n:向前遍历
3.2. 搜索历史命令
我们可以 在增量或非增量模式下搜索命令历史 。对于增量模式,一旦我们开始输入搜索字符串,搜索就会开始:
- CTRL- r:向后搜索
- CTRL- s:正向搜索
3.3. Bash 内置命令
Bash shell 带有 内置的 fc 和 history 命令 。
我们使用 fc 命令主要是对历史列表的一部分进行列出、编辑和重新执行,而我们使用 history 命令来操作历史列表。
首先,让我们看一下 fc 命令。
列出终端上使用的命令:
$ fc -l
39 vi file1
40 ls -la file3
41 ls file3
42 cd ..
43 history
44 ls -la file3
45 ls
46 cd -
47 ls
48 rm file*
49 touch file1 file2 file3 file4
50 ls file3
51 history
如我们所见,我们得到了历史命令的列表。
如果我们想在执行之前编辑命令,我们使用 fc 和不同的选项。下面的所有 fc 命令都在编辑器中打开。 如果最后一个命令是:
$ cat incorrectfilename.demo
然后,执行命令后:
$ fc
编辑器将包含命令或文本:
$ cat incorrectfilename.demo
并且,要在第n个位置编辑命令 ,例如下面列表末尾的第 4 个:
$ fc -4
43 history
44 ls -la file3
45 ls
46 cd -
47 ls
48 rm file*
49 touch file1 file2 file3 file4
50 ls file3
51 history
52 tou
53 fc -l
54 ls file3
在这种情况下,编辑器将包含命令或文本:
$ history
要编辑范围内的命令,我们使用:
$ fc 49 50
编辑器将打开以下行:
$ touch file1 file2 file3 file4
$ ls file3
如果需要,我们可以在编辑器中更改命令。退出编辑器后,执行修改后的命令。
现在,让我们看一下 history 命令。
此命令列出历史文件中所有已执行的命令以及行号:
$ history
33 ls
34 ls
35 pwd
36 pwd
37 set -o history
39 pwd
如果我们想查看最后 n 个执行的命令:
$ history 3
38 set -o history
39 pwd
40 history 3
我们可以使用以下命令执行最后一个命令:
- ⬆️
- !!
- !-1
- CTRL-P
要清除历史记录:
$ history -c
正如预期的那样,如果我们现在执行 历史 命令,只会列出一个命令。
$ history
32 history
要从历史记录中删除特定命令:
$ history -d 32
它将从历史文件中删除事件编号 32。
3.4. 使用简单的历史扩展
除了内置命令之外,history 还具有丰富的功能集。我们使用扩展字符“!” 在历史上的行/命令上。在这里,从历史中选择的命令称为事件,而文字是我们采取行动的事件的一部分。我们还应用修饰符来操纵选定的单词。
如果我们想执行一个 事件 ,请说出历史记录中第 34 行的命令:
!34
要从特定字母开始运行事件,请说从 p开始的 last used 命令:
!p
$ pwd
3.5. 更高级的历史命令
有时,我们想要执行不同的命令,但使用相同的值或参数。为此,我们将使用 词指示符 “!!:$” 。
正如我们在下面看到的, cd 命令 从最后一个事件 ’ ls Demo’中获取参数Demo:
$ ls Demo
file1 file2
$ cd !!:$
$ cd Demo
如果我们想在当前命令上应用最后一个事件的参数,那么我们使用扩展字符’!’ 后跟“^”、“$”或“:n”。
在这里, rm 采用 event touch的第一个参数 并删除 file1。但是,要删除 file4,我们将使用字符 ’ $’。同样,我们将使用“ :2 ”删除 file2:
$ touch file1 file2 file3 file4
$ rm !^
$ rm file1
我们可以操纵事件的另一种方法是使用 修饰符 。在这里,“!to:3”扩展为以文本“to”开头的最后一个事件,在这种情况下是 触摸 命令。之后,它将事件的第三个参数替换为 ls 命令的参数:
touch file1 file2 file3 file4
$ ls !to:3
$ ls file3
file3
3.6. 显示历史中每个命令的日期和时间
默认情况下,大多数 Linux 发行版不显示执行每个命令的日期和时间。我们可以通过临时或永久设置HISTTIMEFORMAT变量来修改此行为。
让我们先看看如何临时设置它:
$ export HISTTIMEFORMAT='%Y-%m-%d %H:%M:%S '
我们正在导出HISTTIMEFORMAT变量并将其设置为标准日期时间格式。
%Y-%m-%d表示以年、月、日开头的日期格式。%H:%M:%S代表小时、分钟和秒。这个方法非常有用,因为它让我们可以更好地控制要显示的内容。
我们可以通过修改命令来简化这种格式:
$ export HISTTIMEFORMAT='%F %T '
在这里,%F扩展为标准日期格式,%T扩展为标准时间格式。 现在让我们运行history命令:
$ history
33 2022-05-03 17:58:33 ls
34 2022-05-04 12:04:44 ls
35 2022-05-04 12:04:57 pwd
36 2022-05-04 12:05:44 export HISTTIMEFORMAT='%F %T '
37 2022-05-04 12:05:44 history
我们可以看到每个命令前面都有它执行的日期和时间。 现在,让我们看看如何永久设置HISTTIMEFORMAT变量。 我们首先需要打开*~/.bashrc*文件:
$ nano ~/.bashrc
然后,我们添加这一行:
export HISTTIMEFORMAT='%F %T '
最后,我们需要运行source 命令来更新我们所做的更改:
$ source ~/.bashrc
现在,每次我们运行history命令时,我们还将获得每个命令执行的日期和时间。