善用Bash history 命令

大家好,我是良许

相信大家平时都有用 history 命令来查看命令历史记录,但是实际上 history 命令并非只有这个功能,history 还有很多有用的功能。尤其是 Bash 版本的 history 命令,它所提供的功能比所有其他的 Linux Shell history 命令所提供的都要多。

Bash 的历史悠久,是一个古老的 Shell ,并且它还有一个更古老的前身 the Bourne Shell (sh) 。因此,Bash 的 history 命令是所有的 Linux Shell history 命令中功能最丰富的。Bash 版本的 history 命令不仅支持反向搜索、快速调用,还支持重写历史记录等等功能。

善用 Bash history 命令以上的这些功能都可以提高你的工作效率,因此,让良许为你一一讲解 Bash history 命令以及它常用的功能:

history 是内置的命令

history 命令与许多其他的命令不同。你可能习惯于命令都作为可执行文件放置在常见的系统级的位置,例如 /usr/bin/usr/local/bin〜/ bin。但是,内置的 history 命令并不在你的环境变量 PATH 保存的路径中的。

实际上,history 命令并没有保存在物理位置中:

$ which history

which: no history in [PATH]

history 其实是 Shell 本身的一个内置函数:

$ type history
history is a shell builtin
$ help history
history: history [-c] [-d offset] [n] or
history -anrw [filename] or
history -ps arg [arg...]

Display or manipulate the history list.
[...]

由于 history 是 Shell 的内置函数,所以每种 Shell 的 history 函数都是独一无二的。因此,你在 Bash 中能使用的功能可能无法在 Tcsh,Fish 或 Dash 中使用,同样的,在 Tcsh,Fish 或 Dash 中能使用的功能也可能无法在 Bash 中使用。

查看你的 Bash 命令历史记录

history 命令最基本,最频繁的用法就是查看你的 Shell 会话的命令历史记录:

$ echo "hello"
hello
$ echo "world"
world
$ history
  1  echo "hello"
  2  echo "world"
  3  history

事件提示符

事件提示符 (!) 是按事件搜索历史记录的。这里的事件,指的是每一条记录在历史记录里的命令。换句话说,它就是一行命令,并被数字索引标记着以供引用。

要重新运行历史记录中的一个命令,用 ! 直接加上 (无空格) 你想要运行的命令前面的索引数字即可。例如,假设历史记录中的第一条指令是 echo hello ,然后你想重新运行它:

$ !1
echo "hello"
hello

你还可以通过从历史记录中的当前位置开始提供负数的行来使用相对定位。例如,返回历史记录中倒数第3条命令:

$ echo "alvin"
alvin
$ echo "hello"
hello
$ echo "world"
world
$ !-3
echo "alvin"
alvin

如果你只想返回上一条命令,你可以使用简写 !! 来替代 !-1。这整整节省了一次按键的时间!!!

$ echo "alvin"
alvin
$ !!
echo "alvin"
alvin

字符串搜索

你也可以通过特定的字符串来搜索历史记录中的命令并运行它。

若是想要搜索以特定字符串开头的命令,就用 ! 直接加上 (无空格) 你想要搜索的字符串:

$ echo "alvin"
alvin
$ true
$ false
$ !echo
echo "alvin"
alvin

你还可以搜索在任意位置包含特定字符串的命令。要做到这点,你只需要用 ! 直接加上前后两端都被 ? 包围的特定字符串即可,像这样:

$ echo "alvin"
alvin
$ true
$ false
$ !?alvin?
echo "alvin"
alvin

如果你知道你想要搜索的字符串在命令的最后面,那就可以省略字符串后面的 ?,像这样:

$ echo alvin
alvin
$ !?alvin
echo alvin
alvin

值得注意的是,若是历史记录中包含目标字符串的命令不止一条,则它只会执行符合条件的命令中最后的一条:

$ echo "hello world"
hello world
$ echo "hello alvin"
hello alvin
$ !?hello?
echo "hello alvin"
hello alvin

字符串替换

你可以搜索一个特定的字符串并用新字符串替换它,从而更改命令:

$ echo "hello"
hello
$ echo "world"
world
$ ^hello^alvin
echo "alvin"
alvin

但是它只能替换第一次出现的目标字符串,若是命令中出现两次目标字符串,则只有第一次出现的会被替换,像这样:

$ echo "hello hello"
hello hello
$ ^hello^alvin
echo "alvin hello"
alvin hello

与字符串搜索一样,当历史记录中包含目标字符串的命令不止一条时,只替换并执行最后一条:

$ echo "hello world"
hello world
$ echo "hello"
hello
$ ^hello^alvin
echo "alvin"
alvin

充分利用 history 命令

实际上,Bash 的 history 命令的功能远不止本文所提到的,但这是你习惯使用 history 命令的一个很好的开始,而不仅仅是利用 history 来查看历史记录。要经常使用 history 命令,看看你只利用 history 命令而不输入具体的指令能完成多少事情,你会被惊艳到的。

最后,希望本文对你的工作有所帮助,如果你对 history 命令还有疑问,或者你还知道 history 命令一些更有用的功能,请留言告诉我呗!

最后,最近很多小伙伴找我要Linux学习路线图,于是我根据自己的经验,利用业余时间熬夜肝了一个月,整理了一份电子书。无论你是面试还是自我提升,相信都会对你有帮助!目录如下:

免费送给大家,只求大家金指给我点个赞!

电子书 | Linux开发学习路线图

也希望有小伙伴能加入我,把这份电子书做得更完美!

有收获?希望老铁们来个三连击,给更多的人看到这篇文章

推荐阅读:

版权声明:本文为yychuyu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yychuyu/article/details/108369245

智能推荐

Tornado day02

一,项目模板: Tornado的项目也可以像Django和flask一样,将功能细分为几个模块 1.1 _ _ init _ _.py 1.2 setting .py 1.3 urls .py 1.4 views .py 1.5 manage .py 将这个模板拷贝下来,以后创建新项目的时候可以直接拷贝一份,在此模板上修改使用 文件链接 链接:https://pan.baidu.com/s/11E...

PAT乙级 | 1095 解码PAT准考证 (25分)(做题过程+注意事项+运行超时解决方法)

PAT 准考证号由 4 部分组成: 第 1 位是级别,即 T 代表顶级;A 代表甲级;B 代表乙级; 第 2~4 位是考场编号,范围从 101 到 999; 第 5~10 位是考试日期,格式为年、月、日顺次各占 2 位; 最后 11~13 位是考生编号,范围从 000 到 999。 现给定一系列考生的准考证号和他们的成绩,请你按照要求输出各种统计信息。 输入格式: 输入首先在一行中给出两个正整数 ...

谈谈Java异常

0 概述 对于java工程师来说,是经常和异常打交道的,本文主要来谈一谈java中的异常。 1 异常类的继承关系 从下图(说明:图中只是列出部分异常类)可以看出: 异常的基类为Throwable,主要分为两个分支,即Error体系和Exception体系。 Exception下面分为RuntimeException和非RuntimeException(如IOException) 2 几种异常的区别...

通过设立FatFS隐藏分区,实现系统文件和用户文件的隔离

嘛。。这是一个关于个人使用FatFS文件系统的 一点小的经验。 我知道大家都会百度和谷歌,关于文件系统有什么用,文件系统怎么移植上自己的平台,看看资料也就懂了,在这里不再详述( 打字太慢一分钟50-60字懒得写)。本系列默认已经可以将设备模拟成u盘,并且已经通过修改diskio.c,可以实现ff.c中的各项功能( 不能实现的自行面壁)。FatFS项目官网 http://elm-chan.org/f...

Mysql之锁与事务知识要点小结

Mysql之锁与事务 平时的业务中,顶多也就是写写简单的sql,连事务都用的少,对锁这一块的了解就更加欠缺了,之前一个大神分享了下mysql的事务隔离级别,感觉挺有意思的,正好发现一个很棒的博文,然后也收集了一些相关知识,正好来学习下,mysql中锁与事务的神秘面纱,主要内容包括 共享锁和排它锁的区别以及适合范围 mysql的表锁和行锁的区别 怎么判断一个sql是否执行了锁,执行的是表锁还是行锁 ...

猜你喜欢

响应式图片二 通过srcset实现

具体方法如下: srcset=”图片地址+空格+尺寸描述符,图片地址+空格+尺寸描述符,图片地址+空格+尺寸描述符….” 浏览器会当前浏览的环境进行感知,这个感知包括网速、界面分辨率、DPR(屏幕像素比)等等,然后在图片中选择一个进行加载。 实际上,在相同DPR下,浏览器会根据屏幕的分辨率加载图片,但是加载了大的图片后再缩小还是会使用大的图片。综合考虑的算法非...

Training_model(2)

已经清洗处理了两个数据文件: application_{train|test}.csv :客户详细信息 bureau.csv : 客户历史信用报告 下面对这两个数据中的特征进行合并,然后Light Gradient Boosting Machine训练模型,之前只用客户数据的预测评分结果是0.734,这次加入了客户信用报告信息 load data 新增加了客户历史信用记录 Build Model ...

微信小程序 页面跳转(传参跟不传参)

跳转页面传参 1.首先我的目录结构是这样的,并在 cinema.wxml 定义了一个点击事件 bindtap=‘indetai’ 2.然后在 cinema.js 的data里面定义了一个 score,并实现了 indetai 方法 3.在 detai.js 的 data 里面也定义一个 score ,再在 onLoad 函数里面接收传递过来的值 4.在页面上显示得到的值 这...

JavaSE 10(二维数组)

前言:      在经历了血雨腥风的地狱模式后本以为迎来了学习的平静,但二维数组又打破了这难得的平静!!!二维数组在java编程中同样也是很重要的知识点,因此在这里我将整理二维数组的知识点与重点,以及习题,便于自己的复习与巩固。 二维数组的声明与创建: 下面是声明二维数组的语法: 数据类型[][]数组名 : 数据类型数组名[][]; (允许这种方式 ,但并不推荐使用它...

深入理解 Linux 内存机制!| 技术头条

作者 | 阿文 责编 | 郭芮 作为一名Linux 系统运维工程,在日常管理 Linux 的时候,我们经常发现系统的空闲内存差不多总是被用完了。   通常,我们可以通过 top 和 free 查看内存使用情况:     执行 free:     为了更人性化地显示,我们可以加上 -h 选项:       可以看到我们的...