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审计与命令记录

原出处:www.pointsoftware.ch/de/howto-bash-audit-command-logger/ 翻译并整理了一下,第一次翻译水平有限,多请见谅。 有一个完整的输入命令记...
  • w18mc0431
  • w18mc0431
  • 2016年08月10日 18:36
  • 707

linux shell 历史命令记录功能

来自:https://segmentfault.com/a/1190000000716056 在 Linux 下面可以使用 history 命令查看用户的所有历史操作,同时 shell 命令操作...
  • shanzhizi
  • shanzhizi
  • 2015年12月09日 13:32
  • 2622

Linux第一课 命令行BASH的基本操作

Linux Bash命令行的基本操作
  • yyywyr
  • yyywyr
  • 2014年12月16日 22:41
  • 1770

Bash记录所有用户的历史记录

bash是多数Linux发行版默认的shell,虽然不及zsh好用,但比其它的shell好太多。 我们的生产服务器很多,没有用跳板机,又是多人共用root用户,为了审计用户操作,需要记录执行命令的用...
  • English0523
  • English0523
  • 2017年02月10日 17:20
  • 338

Shell基础之Bash的基本功能

Shell基础之Bash的基本功能  Bash是众多Shell中Linux使用的一个版本,由于早年的 Unix 年代,发展者众,所以由于 shell 依据发展者的不同就有许多的版本,例如常听到的 B...
  • u010456903
  • u010456903
  • 2015年09月25日 21:44
  • 1504

linux中source、bash命令区别

source命令用法:   source FileName   作用:在当前bash环境下读取并执行FileName中的命令。该filename文件可以无"执行权限"     注:该命令通常用命...
  • yu1013708633
  • yu1013708633
  • 2016年02月16日 15:58
  • 1856

Bash:command:未找到命令

前言     在Linux系统中,经常会遇到这样的问题:bash:command:未找到命令。        这个真的很烧脑,遇到的次数多,在网上也查了好多,答案五花八门,有解决的了有不能...
  • weienjun
  • weienjun
  • 2017年06月19日 17:19
  • 2425

Linux基本bash命令(持续更新)

首先了解下shell Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。 以下是几种shell版本,bash是默认...
  • u012442157
  • u012442157
  • 2017年06月24日 15:47
  • 579

实用bash命令记录

本篇文章记录工作中比较实用,能减轻工作量的bash命令。 1.字符串截取 假设有这么一个变量silo=/home/liujiacai/codes/cascalog/silo,那么 ${silo##/*...
  • on_way_
  • on_way_
  • 2014年01月16日 16:12
  • 913

完善bash历史命令审核

1. 下载bash-4.2版本源码包,修改其中的源代码重新编译安装: wget http://mirrors.ustc.edu.cn/gnu/bash/bash-4.2.tar.gz ...
  • reyleon
  • reyleon
  • 2013年12月20日 18:15
  • 1118
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Bash之命令历史的存储和记录
举报原因:
原因补充:

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