Contents

在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命令时,我们还将获得每个命令执行的日期和时间。