公众号旧文

让服务器 history 显示时间并保留多行命令

作者:胖子阅读 —

很多 Linux 服务器默认的 history 功能比较简单。

默认输出序号和历史命令:

1001 ls
1002 cd /opt
1003 vim test.sh

但有两个明显问题:

  1. 不知道命令是什么时候执行的
  2. 多行 Shell 语句会被拆得七零八落

例如:

while read -r host; do
    ssh "$host" hostname
done < hosts.txt

历史记录可能变成:

1201 while read -r host; do
1202 ssh "$host" hostname
1203 done < hosts.txt

时间长了几乎无法审计和追溯。

本文介绍如何把 Bash 历史记录升级为更友好的版本。

一、开启时间戳

编辑:

vim ~/.bashrc

加入:

export HISTTIMEFORMAT="%F %T "

重新加载:

source ~/.bashrc

再次查看历史:

history

效果:

1001  2026-06-09 22:30:01 ls
1002  2026-06-09 22:30:08 cd /opt
1003  2026-06-09 22:30:15 vim test.sh

其中:

  • %F = YYYY-MM-DD
  • %T = HH:MM

二、扩大历史记录容量

默认很多发行版仅保存:

HISTSIZE=1000
HISTFILESIZE=2000

对于运维人员来说远远不够。

建议修改为:

HISTSIZE=100000
HISTFILESIZE=200000

含义:

HISTSIZE      当前 Shell 保留 100000 条
HISTFILESIZE  历史文件保留 200000 条

三、避免覆盖历史记录

开启追加模式:

shopt -s histappend

这样多个登录会话退出时不会互相覆盖历史文件。

四、立即写入历史文件

默认 Bash 在退出时才写入:

命令
↓
内存
↓
退出 Shell
↓
写入 ~/.bash_history

如果 SSH 断开或者终端崩溃,最近执行的命令可能丢失。

建议加入:

PROMPT_COMMAND="history -a"

这样每执行一条命令都会立即写入:

命令
↓
立即写入 ~/.bash_history

安全得多。

五、保留多行命令结构

这是很多人忽略的配置。

加入:

shopt -s cmdhist
shopt -s lithist

作用:

cmdhist

允许 Bash 将多行命令合并保存。

lithist

保留原始换行格式。

例如:

while read -r host; do
    ssh "$host" hostname
done < hosts.txt

开启前:

while read -r host; do
ssh "$host" hostname
done < hosts.txt

开启后:

while read -r host; do
    ssh "$host" hostname
done < hosts.txt

可读性大幅提升。

六、推荐最终配置

将以下内容加入 ~/.bashrc:

# History
HISTCONTROL=ignoreboth
HISTSIZE=100000
HISTFILESIZE=200000
export HISTTIMEFORMAT="%F %T "
shopt -s histappend
shopt -s cmdhist
shopt -s lithist
PROMPT_COMMAND="history -a"

重新加载:

source ~/.bashrc

七、验证是否生效

查看最近历史:

history | tail

输出类似:

1768  2026-06-09 23:00:36 pwd
1769  2026-06-09 23:02:01 cat ~/.bash_history
1770  2026-06-09 23:02:48 cat ~/.bashrc
1771  2026-06-09 23:03:56 nano ~/.bashrc
1772  2026-06-09 23:04:26 cat ~/.bashrc
1773  2026-06-09 23:04:43 source ~/.bashrc

检查历史文件:

tail -20 ~/.bash_history

会看到:

#1781017368
cat ~/.bashrc
#1781017436
nano ~/.bashrc
#1781017483
source ~/.bashrc

这些以 # 开头的数字是 Unix 时间戳,说明 Bash 已经在记录执行时间。

总结

对于服务器运维来说,建议至少启用以下四项:

export HISTTIMEFORMAT="%F %T "
shopt -s histappend
shopt -s cmdhist
shopt -s lithist
PROMPT_COMMAND="history -a"

这样不仅能知道执行过什么命令,还能知道:

  • 什么时间执行的
  • 多行脚本原本长什么样
  • SSH 意外断开后不会丢历史
  • 多终端登录不会覆盖历史

对于排障、审计和日常运维都非常实用。