Linux history 命令相关使用以及配置

Posted 青冬

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux history 命令相关使用以及配置相关的知识,希望对你有一定的参考价值。

Linux history 命令相关使用以及配置

Linux history

新手学习 shell 的时候都知道 history 命令能帮助我们查看之前运行的命令集合,通过这个能够帮我们回忆之前的命令,以及进行各种排错等等。

比如我们直接输入 history 进行查看:

history [N]
history 5 # 仅仅显示最后5行

history 使用

history [N]

查看最后 5 条历史命令

history 5

history -c

清空历史命令

history -c

history -d offset

指定删除第几个命令的记录

history -d 100 # 删除第100条命令

history -anrw [filename]

-a 追加本次会话执行的命令历史列表,保存到历史文件中。

-n 将历史文件中新增的部分加载到内存中,可以方便多端同步。

-r 读取历史文件中的所有命令在内存中,即使已经加载过

-w 将历史文件写出到 [filename] 中

history -anrw /root/.bash_history

ps: 使用 man 命令可以查看 history 的详细使用

history -p arg [arg …]

进行打印,但是不记录在历史记录中,有点像 echo arg[arg…] 但并不会被历史命令记录

history -p  $HISTTIMEFORMAT 
# 但如果有空格则会换行进行打印

history -s arg [arg …]

伪造命令,相当于直接添加这条命令到历史记录中,但并不会真正执行

history -s rm -rf /*
# 构造了一条 rm -rf /* 的命令

history 配置

HISTTIMEFORMAT hisotry 打印格式

如上面所示,我们在查看历史记录的时候,并没有记录这条命令的运行时间,但其实是可以配置的。

vim /etc/bashrc
# or
vim /etc/profile
# or
vim /etc/profile.d/history.sh #最推荐这个

# 在这些文件中追加
export HISTTIMEFORMAT="%Y-%m-%d %H:%M "
# 注意初次更改时,之前的命令会记录为更改的时刻。

可以看到,如果我们将 HISTTIMEFORMAT 更改为对应的 format 格式,那么 history 命令打印的格式也会变更。甚至我们可以在上面运行一些其他命令当做参数补充:

export HISTTIMEFORMAT="%Y-%m-%d %H:%M:%S  `who am i | awk 'print $1,$5'` "

配置历史记录最大条数

之前的篇幅讲过,在我们的环境变量里面有一个变量可以更改我们 history 命令的最大长度,默认是 1000:

set |grep HISTSIZE # 定义的是 history 输出命令的记录数
# HISTSIZE=1000
set |grep HISTFILESIZE # 定义的是 .bash_history 中的记录总数
# HISTFILESIZE =1000

这个参数在 /etc/profile 中被定义:

cat /etc/profile |grep HISTSIZE
# HISTSIZE=1000
# export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL

可以看到,这个参数也是在 /etc/profile.d/* 之前被定义的,所以如果我们想更改也可以

echo 'export HISTSIZE=2000' >> /etc/profile.d/history.sh
echo 'export HISTFILESIZE=2000' >> /etc/profile.d/history.sh
chmod 755 /etc/profile.d/history.sh

HISTSIZE & HISTFILESIZE

HISTSIZE 标示在 history 命令中,要记录的命令数量

如果为 0, 则不进行记录

如果小于 0,则永远记录

如果大于 0,则仅记录这个数值

HISTFILESIZE 标示在历史文件 .bash_history 中的记录数。

如果为 0, 则不进行记录

如果小于 0,则永远记录

如果大于 0,则仅记录这个数值

当 shell 退出时,才会将缓存中的数据写出到这个文件。

HISTIGNORE

这个变量是运维比较头疼的环境变量,可以忽略某些常见命令,不保存在命令历史中。

export HISTIGNORE="pwd:df:du:rd*" # 以:为分隔符进行切分匹配
rd1
rd2
rd3
4rd
r5d
history | tail

可以看到,我们配置忽略 rd 开头的命令后,前面执行的三条命令不存在了,只剩下 4rd 和 r5d 两条命令。

HISTFILE

这个变量决定了我们的 history 文件写出在哪里,默认为本用户目录下的 .bash_history 文件。

echo $$HISTFILE
# ~/.bash_history

当然当我们启动 bash 的时候,变量 $HISTFILE 所指向的文件会被读取,让当前会话能够加载之前的历史命令。

histappend

if (history_lines_this_session <= where_history() || force_append_history)
    append_history (history_lines_this_session, hf);
else
    write_history (hf);
sv_histsize ("HISTFILESIZE");

当存储到文件时,Bash 会将此前会话中的命令直接存储到文件末尾,如果文件的记录数大于定义的最大记录数,则清空旧的历史命令,并且当下次再存储时会重写此前文件。

如果 histappend (force_append_history)设置是启动的,那么当前会话退出时,最后执行的 $HISTSIZE 行会被拷贝进 $HISTFILE 中,不考虑大小。

# 使用 shopt (shell option) 来查看 histappend 是否开启
shopt histappend 
# histappend      on

命令记录模式

存储操作最终还是归集于存储介质的读写操作,如对文件的读写,增加的只是对业务逻辑规则的各种限制。

命令可以在执行命令时记录,也可以在命令刚输入,但已经识别的情况下记录,Bash 属于后者。

Bash 在 yacc 做语法分析时将用户输入的命令通过 maybe_add_history 函数写入到当前会话的命令历史记录表中。

在做语法分析时就已经记录了用户输入的命令,此时记录就不用管命令最终的结果是怎样,也不用管如果执行过程出了异常会怎样处理。

它只是如实的在执行前记录用户输入的什么命令,由此,我们可以知道 Bash 的命令历史记录的定义为用户输入的命令历史记录。

多终端问题

我们知道相同的用户也可以在同一台服务器开启多个终端,那么这些终端都会产生不同的历史记录:

当我们用户退出当前会话的时候,才会把缓存中的内容写入到 ~/.bash_history 中,那么意味着如果我当前终端不释放,其他终端是感知不到我当前终端运行的命令。

~/.bash_history 在之前也讲过,是存储最后 $HISTFILESIZE 条历史命令的。

如果我们想要一个用户的多端都同步历史 shell 命令可以这样配置

export PROMPT_COMMAND='history -a;history -r;'

但十分不推荐这样做,因为很多时候其实我们并不希望多端同步,而且会花费较多性能。

以上是关于Linux history 命令相关使用以及配置的主要内容,如果未能解决你的问题,请参考以下文章

Linux系统history命令小技巧

linux如何屏蔽history命令

[转帖]linux 清空history以及记录原理

Linux历史命令管理以及用法

Linux常用命令--history随记

如何清除linux的history 命令历史记录