Bash之命令历史的存储和记录

转载 2013年12月03日 22:41:24

//ps: 这篇文章系bash的history相关,多了解点儿也好!不同session的history操作同步问

在Bash中我们可以使用 history 命令回顾,修改和重用之前使用过的历史命令。去掉信号机制、去掉作业控制、去掉各种参数调用,今天我们只看下Bash中如何记录命令,如何存储历史命令。

在 Bash 的源代码中,history 命令的定义代码为 builtins/history.def , builtins 目录下存放的是内部命令的源代码,每个内部命令是一个def文件,如history.def,cd.def等。 Makefile中DEFSRC声明了所有内部命令的def文件。由 mkbuiltins.c 生成编译时辅助工具 mkbuiltins,mkbuiltins 处理 *.def 文件,生成命令的 *.c 源程序以及 builtins.c 、 builtext.h。 builtins.c 和 builtext.h 相当于各个内部命令的索引

history.def 的作用是解析命令并将不同的参数分发命令到不同的功能实现,如读取命令、覆盖命令等。一些功能实现代码文件在 bashhist.c/bashhist.h,但是关于历史记录的基础操作并不在这两个文件中,它们在 lib/readline 中。这是因为 Bash 采用的GNU Readline函数库中。 Readline提供了统一的行编辑和历史记录功能的命令行交互方式。

history命令在显示时会显示所有的历史记录,这里的所有历史记录包括最开始从文件中读取的历史记录,还包括当前会话产生的记录。假设你的历史记录中已经有了500条命令,如果你用其它文档编辑器将历史日志文件写到1000条,打开终端,你会发现显示的还只有500记录。这是因为在打开终端初始化时,不仅仅有历史记录列表的读操作,还会有关于文件记录数限制的初始化操作,确保文件中的记录条数不会大于设定的最大值。这个初始化操作在 load_history 函数中实现,函数最开始就做了两次历史记录文件的截取操作,一次是默认500,一次是设置的最大值: HISTFILESIZE 。

在历史记录中有一个会话的概念,不同会话中的命令在没有保存到文件前是不会互相冲突的。比如,打开终端A如果你删除 .bash_history 的前10行命令,保存,在命令行中输入history,你会发现输出的命令历史记录并不是从1开始,而是从11开始的。如果此时,你再开一个终端B,输入若干条命令后,再输入history,你会发现历史记录中没有在终端A输入的命令。这是由于在一个终端会话中,历史记录从固化存储位置的读取操作只有一次,写入操作也只有一次,即在打开终端时读取,在关闭终端时写入。

除了文件存储,历史记录也可以记录在MMAP,对应的宏定义为 HISTORY_USE_MMAP。

如果以文件存储方式,命令记录以一行一条命令的方式存储在.bash_history(默认,如果有设置 HISTFILE 则优先使用 HISTFILE 中的值),虽然我们使用 history 命令时看到每条命令前都会有一个标号,我们可以使用 !标号 的方式重新执行命令,这个标号并不是唯一不变的,标号是在初始化时在读取文件时在程序操作中标记的,后续有命令加入时,标号会自增,这个自增并不会受历史记录的最大值限制。

当一次会话退出时保存历史记录文件,将历史数据固化存储,并将会话统计清零。当存储到文件时,Bash 会将此前会话中的命令直接存储到文件末尾,如果文件的记录数大于定义的最大记录数,则清空旧的历史命令,并且当下次再存储时会重写此前文件。代码示例如下:


存储操作最终还是归集于存储介质的读写操作,如对文件的读写,增加的只是对业务逻辑规则的各种限制。命令可以在执行命令时记录,也可以在命令刚输入,但已经识别的情况下记录,Bash 属于后者。 Bash 在 yacc 做语法分析时将用户输入的命令通过 maybe_add_history 函数写入到当前会话的命令历史记录表中。在做语法分析时就已经记录了用户输入的命令,此时记录就不用管命令最终的结果是怎样,也不用管如果执行过程出了异常会怎样处理。它只是如实的在执行前记录用户输入的什么命令,由此,我们可以定义 Bash 的命令历史记录的定义为用户输入的命令历史记录。

参考资料: http://files.linjian.org/articles/techreport/bash_study.tar.gz



举报

相关文章推荐

Bash的应用--2.命令历史记录

Bash的应用   二、命令历史记录 Bash支持命令历史记录,这意味着Bash保留了一定数目的、先前在Bash中输入过的命令。这个数目取决于一个名为HISTSIZE的变量。 Bash将输入的...

Bash和Ksh中查找和执行历史命令

在Linux的Bash环境中,可以比较方便的搜索和执行最近输入过的命令,其实,在Unix的Ksh环境中,也可以做到,不过方法有所不同。总结这两种shell环境下相关的历史命令操作如下: #Bas...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

linux - Bash的基本功能(历史命令)

1.历史命令 我们直接输入 history 会显示我们输入所有的历史命令,每个用户都可以查看到自己输入的历史命令,都有保存自己历史命令的文件,这样就不会冲突,我们直接输入 history  查看...

shell基础-bash基本功能-历史命令与补全

1. 历史命令命令格式:history [选项] [历史命令保存文件]选项: -c:清空所有的历史命令 -w:把缓存中的历史命令立即写入历史命令保存文件(默认保存位置为登录用户家目录下的.bash_h...

bash记录所有用户的历史记录,监控用户一举一动

https://www.52os.net/articles/bash-log-all-history-to-syslog.html?utm_source=tuicool&utm_medium=refe...
  • sfdst
  • sfdst
  • 2016-06-01 14:23
  • 232

翻译_bash:bash命令行下如何引用历史命令的参数

本文来自stackoverflow一个问答,提及的
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)