返工途中,大家一路平安
一,什么是history 相关环境变量介绍
以下是相关的环境变量,今天重点介绍HISTFILE
二,history 实现机制
源码位置
https://gitee.com/AprilSloan/bash/blob/master/lib/readline/history.c
1.Bash 的源码中(如 history.c 和 variables.c),以下函数处理 HISTFILE 相关逻辑:
history_initialize()初始化历史记录模块,读取 HISTFILE 或创建默认文件。add_history()write_history()将内存中的历史记录写入 HISTFILE(默认在 Shell 退出时调用)。read_history()stifle_history()根据 HISTSIZE 和 HISTFILESIZE 截断历史记录。
bash/├── history.c # 历史命令相关实现├── variables.c # 变量管理相关实现├── bashline.c # 命令行编辑├── builtins/ # 内置命令│ ├── history.def # history 命令实现│ └── ...├── lib/│ └── history/ # 历史库(readline 相关)│ ├── history.c│ ├── histfile.c│ └── ...├── lib/readline/ # 行编辑库
2. HISTFILE 的工作流程
2.1 启动时:加载历史记录
- 读取
HISTFILE
Bash 启动时调用 read_history(),从 HISTFILE(默认 ~/.bash_history)逐行读取命令,填充到内存历史列表。- 若文件不存在,则创建空文件(除非
HISTFILE 被显式设为 /dev/null)。
- 应用
HISTSIZE 和 HISTFILESIZE HISTSIZE:限制内存中保留的历史条数(超出部分从头部丢弃)。HISTFILESIZE:限制 HISTFILE 的最大行数(超出部分从文件头部截断)。
2.2 运行时:管理历史记录
- 添加新命令
- 每次执行命令后,Bash 调用
add_history() 将命令追加到内存历史列表。 - 若启用
HISTCONTROL(如 ignoredups),会跳过重复命令。
- 实时保存(可选)
- 通过
PROMPT_COMMAND 设置(如 export PROMPT_COMMAND="history -a"),可在每次提示符显示前调用 history -a,将内存历史追加到 HISTFILE。
2.3 退出时:保存历史记录
- 调用
write_history() - Bash 退出时(或执行
exit/Ctrl+D),将内存历史写入 HISTFILE。 - 默认行为是覆盖文件,但可通过
shopt -s histappend 改为追加模式。
- 截断历史文件
- 若
HISTFILESIZE 小于当前文件行数,Bash 会从文件头部删除旧条目,确保文件大小不超过限制。
三,用法
1. 查看当前设置
# 查看历史文件路径 ⚡ root@localhost ~ echo $HISTFILE/root/.zsh_history# 输出示例:/home/user/.bash_history# 查看历史命令数量限制 ⚡ root@localhost ~ echo $HISTSIZE50000# 查看历史文件内容 ⚡ root@localhost ~ cat ~/.zsh_history : 1771071487:0;ls: 1771140221:0;hist: 1771140230:0;history# 查看当前会话历史命令 ✘ ⚡ root@localhost ~ history 1 ls 2 hist 3 history
2. 修改历史文件路径和其它基本配置
# 临时修改(当前会话生效) ⚡ root@localhost ~ export HISTFILE=~/.my_custom_history ⚡ root@localhost ~ echo $HISTFILE /root/.my_custom_history# 永久修改(写入 ~/.bashrc),在此不演示echo 'export HISTFILE=~/.my_custom_history' >> ~/.bashrcsource ~/.bashrc#增加历史记录数量# 在 ~/.bashrc 中添加export HISTSIZE=10000export HISTFILESIZE=20000# 使配置生效source ~/.bashrc#禁用历史记录(安全敏感场景)# 方法1:指向 /dev/nullexport HISTFILE=/dev/null# 方法2:清空并设为只读unset HISTFILEreadonly HISTFILE# 方法3:在 ~/.bashrc 中条件禁用if [ "$USER" = "root" ]; then export HISTFILE=/dev/nullfi#多会话历史隔离# 每个终端使用独立历史文件export HISTFILE=~/.bash_history_$(tty | sed 's/\//_/g')# 或使用会话 IDexport HISTFILE=~/.bash_history_$$#多会话历史共享(实时同步)# 在 ~/.bashrc 中添加export PROMPT_COMMAND="history -a; history -n; ${PROMPT_COMMAND}"# 说明:# history -a 将当前会话历史追加到文件# history -n 从文件读取其他会话的新历史
安全相关用法
#忽略敏感命令# 在 ~/.bashrc 中添加export HISTIGNORE="*password*:*secret*:*ssh*:sudo rm*:curl*wget*"# 忽略以空格开头的命令(前面加空格不记录)export HISTCONTROL=ignorespace# 忽略重复命令export HISTCONTROL=ignoredups# 同时忽略空格开头和重复命令export HISTCONTROL=ignoreboth#临时禁用某条命令记录# 命令前加空格(需设置 HISTCONTROL=ignorespace) ssh user@server# 或使用 unset 临时禁用unset HISTFILE# 执行敏感命令# 恢复export HISTFILE=~/.bash_history#审计场景(强制记录)# 在 /etc/profile 中强制设置(对所有用户生效)export HISTFILE=/var/log/bash_history_$USERexport HISTSIZE=10000export HISTFILESIZE=50000export PROMPT_COMMAND="history -a"# 设置文件权限(防止用户修改)chmod 444 /var/log/bash_history_$USERchattr +a /var/log/bash_history_$USER # 只追加
历史命令操作技巧
搜索历史命令# 搜索包含关键词的历史命令 ⚡ root@localhost ~ history | grep "ls" 1 ls 17 ls 19 ls 27 ls 29 ls# 使用 Ctrl+R 反向搜索(交互模式)# 按 Ctrl+R 后输入关键词# 使用 ! 快速执行 ⚡ root@localhost ~ !ls ⚡ root@localhost ~ ls # 执行最近一条包含 ls 的命令 ⚡ root@localhost ~ !! ⚡ root@localhost ~ ls # 执行上一条命令 ⚡ root@localhost ~ !-3 ⚡ root@localhost ~ echo $HISTFILE # 执行倒数第3条命令#导出/备份历史# 将当前历史写入文件history -w# 从文件读取历史history -r# 备份历史文件cp ~/.bash_history ~/.bash_history.backup.$(date +%Y%m%d)# 合并多个历史文件cat ~/.bash_history_* >> ~/.bash_history_merged# 清空当前会话历史history -c# 清空历史文件> ~/.bash_history# 清空并退出history -c && history -w && exit
实用配置模板
推荐 ~/.bashrc 配置# ========== 历史命令配置 ==========export HISTFILE=~/.bash_historyexport HISTSIZE=10000export HISTFILESIZE=20000# 忽略重复和空格开头的命令export HISTCONTROL=ignoreboth# 忽略敏感命令export HISTIGNORE="*password*:*secret*:ls:cd:exit"# 多会话实时同步export PROMPT_COMMAND="history -a; history -n"# 显示时间戳(便于审计)export HISTTIMEFORMAT="%F %T "
四,快速参考表
| |
|---|
| echo $HISTFILE |
| export HISTFILE=~/.xxx |
| export HISTSIZE=10000 |
| export HISTFILE=/dev/null |
| export HISTIGNORE="*password*" |
| export PROMPT_COMMAND="history -a; history -n" |
| export HISTTIMEFORMAT="%F %T " |
| history -c |
| history -w |
| history -r |
五,总结
以上是今天全部内容
最后的最后(Last but not least),欢迎交流:
关注公众号留言,或者在下方直接留言: