如何在 Linux 上使用 history 命令

Linux 的 shell 保存了您运行的命令的历史记录,您可以搜索它以重复您过去运行过的命令。 一旦您了解了 Linux 历史命令以及如何使用它,它就可以显着提高您的工作效率。

操纵历史

作为 乔治桑塔亚纳有句名言,“那些不记得过去的人注定要重蹈覆辙。” 不幸的是,在 Linux 上,如果您不记得过去,即使您愿意,也无法重复。

这时候 Linux 历史命令就派上用场了。 它允许您查看和重复以前的命令。 这不仅仅是为了鼓励懒惰或节省时间——还有一个效率(和准确性)因素在起作用。 命令越长越复杂,就越难记住和键入而不会出错。 有两种类型的错误:一种阻止命令工作,另一种允许命令工作,但使其执行意外操作。

history 命令消除了这些问题。 像大多数 Linux 命令一样, 它比你想象的要多. 但是,如果您学习如何使用 history 命令,它可以提高您每天使用 Linux 命令行的能力。 这是您时间的一项很好的投资。 使用历史命令有比重复点击向上箭头更好的方法。

历史命令

以最简单的形式,您可以通过输入历史命令的名称来使用它:

history

这

然后将先前使用的命令列表写入终端窗口。

的输出示例

这些命令被编号,最近使用的(编号最高的)位于列表的末尾。

要查看一定数量的命令,您可以在命令行上将一个数字传递给历史记录。 例如,要查看您最近使用的 10 个命令,请键入以下内容:

history 10

这

如果通过管道传输历史记录,您可以获得相同的结果 尾部命令. 为此,请键入以下内容:

history | tail -n 10

这

重复命令

如果要重用历史列表中的命令,请键入感叹号 (!) 和命令编号,中间不带空格。

例如,要重复第 37 条命令,您可以键入以下命令:

!37

一个

要重复最后一个命令,请再次键入两个感叹号,不带空格:

!!

一个

当您发出命令并忘记使用 sudo 时,这可能很有用。 键入 sudo、一个空格、双感叹号,然后按 Enter。

对于以下示例,我们键入了一个需要 sudo 的命令。 无需重新输入整行,我们可以节省一堆击键,只需输入 sudo !!,如下所示:

mv ./my_script.sh /usr/local/bin/
sudo !!

一个

因此,您可以从列表中键入相应的数字来重复命令或使用双感叹号重复您使用的最后一个命令。 但是,如果您想重复第五条或第八条命令怎么办?

您可以使用一个感叹号、一个连字符 (-) 和任何先前命令的编号(同样,不带空格)来重复它。

要重复前面的第 13 个命令,您将键入以下内容:

!-13

一个

按字符串搜索命令

要重复以特定字符串开头的最后一个命令,您可以键入感叹号,然后键入不带空格的字符串,然后按 Enter。

例如,要重复以 sudo 开头的最后一个命令,您可以键入以下命令:

!sudo

一个

不过,这其中有一个危险因素。 如果最后一个以 sudo 开头的命令不是您认为的那样,您将启动错误的命令。

但是,为了提供安全网,您可以使用 :p (打印)修饰符,如下所示:

!sudo:p

一个

这指示历史将命令打印到终端窗口,而不是执行它。 这使您可以在使用命令之前查看它。 如果它是您想要的命令,请按向上箭头,然后按 Enter 以使用它。

如果要查找包含特定字符串的命令,可以使用感叹号和问号。

例如,要查找并执行包含单词“aliases”的第一个匹配命令,您可以键入以下命令:

!?aliases

一个

这将找到包含字符串“aliases”的任何命令,无论它出现在字符串中的什么位置。

交互式搜索

交互式搜索允许您浏览匹配命令列表并重复您想要的命令。

只需按 Ctrl+r 即可开始搜索。

之后的终端窗口

当您键入搜索线索时,将出现第一个匹配的命令。 您键入的字母出现在反引号 (`) 和撇号 (‘) 之间。 匹配的命令会随着您键入每个字母而更新。

一个

每次按 Ctrl+r 时,都会向后搜索下一个匹配的命令,该命令会出现在终端窗口中。

一个

当您按 Enter 时,将执行显示的命令。

这

要在执行命令之前对其进行编辑,请按向左或向右箭头键。

一个

该命令出现在命令行上,您可以对其进行编辑。

您可以使用其他 Linux 工具来搜索历史列表。 例如,将历史记录的输出通过管道传输到 grep 和 搜索包含字符串的命令 “别名”你可以使用这个命令:

history | grep aliases

这

修改最后一条命令

如果您需要更正错字,然后重复该命令,您可以使用插入符号 (^) 进行修改。 每当您拼错命令或想要使用不同的命令行选项或参数重新运行命令时,这是一个很好的技巧。

要使用它,请键入(不带空格)一个插入符号、要替换的文本、另一个插入符号、要替换它的文本、另一个插入符号,然后按 Enter。

例如,假设您键入以下命令,不小心键入了“shhd”而不是“sshd”:

sudo systemctl start shhd

您可以通过键入以下内容轻松更正此问题:

^shhd^sshd^

一个

执行命令时将“shhd”更正为“sshd”。

从历史列表中删除命令

您还可以使用 -d(删除)选项从历史列表中删除命令。 没有理由将拼写错误的命令保留在历史列表中。

您可以使用 grep 找到它,使用 -d 选项将其编号传递给历史记录以删除它,然后再次搜索以确保它已消失:

history | grep shhd
history -d 83
history | grep shhd

这

您还可以将一系列命令传递给 -d 选项。 要删除从 22 到 32(含)的所有列表条目,请键入以下命令:

history -d 22 32

要仅删除最后五个命令,您可以键入一个负数,如下所示:

history -d -5

手动更新历史文件

当您登录或打开终端会话时,会从历史文件中读入历史列表。 在 Bash 中,默认的历史文件是 .bash_history。

您在当前终端窗口会话中所做的任何更改只会在您关闭终端窗口或注销时写入历史文件。

假设您要打开另一个终端窗口来访问完整的历史列表,包括您在第一个终端窗口中键入的命令。 -a(全部)选项允许您在打开第二个终端窗口之前在第一个终端窗口中执行此操作。

要使用它,请键入以下内容:

history -a

这

命令以静默方式写入历史文件。

如果要将历史列表的所有更改写入历史文件(例如,如果您删除了一些旧命令),可以使用 -w(写入)选项,如下所示:

history -w

这

清除历史列表

要从历史列表中清除所有命令,可以使用 -c(清除)选项,如下所示:

history -c

如果您还想强制对历史文件进行这些更改,请使用 -w 选项,如下所示:

history -w

安全性和历史文件

如果您使用任何需要您在命令行上输入敏感信息(如密码)的应用程序,请记住这也将保存在历史文件中。 如果您不想保存某些信息,可以使用以下命令结构立即将其从历史列表中删除:

special-app my-secret-password;history -d $(history 1)
history 5

一个

此结构包括两个用分号 (;) 分隔的命令。 让我们分解一下:

special-app:我们正在使用的程序的名称。
my-secret-password:我们需要在命令行上为应用程序提供的秘密密码。 这是命令一的结束。
历史 -d:在命令二中,我们调用历史的 -d(删除)选项。 我们要删除的是命令的下一部分。
$(history 1):这使用命令替换。 $() 中包含的命令部分在子shell 中执行。 该执行的结果作为文本发布在原始命令中。 history 1 命令返回前一个命令。 因此,您可以将第二个命令视为 history -d “last command here”。

您可以使用 history 5 命令确保从历史列表中删除包含密码的命令。

不过,还有一种更简单的方法可以做到这一点。 因为 Bash 默认会忽略以空格开头的行,所以只需在行首包含一个空格,如下所示:

 special-app another-password
history 5

一个

带有密码的命令不会添加到历史列表中。 这个技巧起作用的原因包含在 .bashrc 文件中。

.bashrc 文件

每次登录或打开终端窗口时都会执行 .bashrc 文件。 它还包含一些控制历史命令行为的值。 让我们用 gedit 编辑这个文件。

键入以下内容:

gedit .bashrc

这

在文件顶部附近,您会看到两个条目:

HISTSIZE:历史列表可以包含的最大条目数。
HISTFILESIZE:历史文件可以包含的行数限制。

这两个值以下列方式相互作用:

当您登录或启动终端窗口会话时,历史列表将从 .bash_history 文件中填充。
当您关闭终端窗口时,在 HISTSIZE 中设置的最大命令数将保存到 .bash_history 文件中。
如果启用了 histappend shell 选项,则命令将附加到 .bash_history。 如果未设置 histappend,则覆盖 .bash_history。
将历史列表中的命令保存到 .bash_history 后,历史文件被截断为不超过 HISTFILESIZE 行。

同样在文件顶部附近,您会看到 HISTCONTROL 值的条目。

这

您可以设置此值以执行以下任何操作:

ignorespaces:以空格开头的行不会添加到历史列表中。
ignoreups:重复的命令不会添加到历史文件中。
ignoreboth:启用以上两项。

您还可以列出不想添加到历史列表中的特定命令。 用冒号 (:) 分隔这些内容,并将它们放在引号中 (“…”)。

您将按照此结构在 .bashrc 文件中添加一行,并替换您希望被忽略的命令:

export HISTIGNORE="ls:history"

一个

使用时间戳

如果要将时间戳添加到历史列表中,可以使用 HISTIMEFORMAT 设置。 为此,您只需在 .bashrc 文件中添加如下一行:

export HISTTIMEFORMAT="%c "

请注意,右引号前有一个空格。 这可以防止时间戳与命令列表中的命令对接。

一个

现在,当您运行 history 命令时,您会看到日期和时间戳。 请注意,添加时间戳之前历史​​列表中的任何命令都将使用第一个接收时间戳的命令的日期和时间进行时间戳。 在下面显示的示例中,这是命令 118。

这是一个非常冗长的时间戳。 但是,您可以使用 %c 以外的标记来改进它。 您可以使用的其他令牌是:

%d: 天
%m:月
%y:年份
%H:小时
%M:分钟
%S:秒
%F:完整日期(年-月-日格式)
%T:时间(时:分:秒格式)
%c:完整的日期和时间戳(日-日-月-年,时:分:秒格式)

让我们尝试并使用一些不同的令牌:

export HISTTIMEFORMAT="%d n%m %T "

导出 HISTTIMEFORMAT=

输出使用日、月和时间。

但是,如果我们删除日期和月份,它只会显示时间。

您对 HISTIMEFORMAT 所做的任何更改都会应用到整个历史列表。 这是可能的,因为每个命令的时间都存储为 从 Unix 纪元开始的秒数. HISTTIMEFORMAT 指令仅指定用于将该秒数呈现为人类可读样式的格式,例如:

export HISTTIMEFORMAT="%T "

这

我们的输出现在更易于管理。

您还可以使用 history 命令进行审计。 有时,查看您过去使用过的命令可以帮助您确定可能导致问题的原因。

就像在生活中一样,在 Linux 上,您可以使用 history 命令重温美好时光并从坏境中吸取教训。