history 是 Shell 交互式操作的「時光機」,記錄每一條敲入的命令,支援快速重執行、搜索、審計與自動化。但預設配置往往不夠安全、不夠高效。本文系統講解 history 核心機制、環境變量調優、進階調用技巧、時間戳審計與安全最佳實踐,讓命令歷史成為生產力倍增器而非風險源。
HISTSIZE 限制。~/.bash_history(或 $HISTFILE 指定),受 HISTFILESIZE 限制。| 變量 | 預設值 | 推薦生產值 | 作用 |
|---|---|---|---|
HISTSIZE | 1000 | 5000~10000 | 記憶體中保留的命令條數 |
HISTFILESIZE | 2000 | 20000~50000 | 歷史文件最大行數 |
HISTFILE | ~/.bash_history | ~/.bash_history_$(hostname) | 自定義歷史文件路徑(多主機區分) |
HISTCONTROL | 空 | ignoredups:erasedups | ignoredups忽略連續重複 erasedups刪除歷史中所有重複 |
HISTIGNORE | 空 | ls:pwd:exit:clear:history*:bg:fg | 不記錄的命令模式(冒號分隔,支援通配符) |
HISTTIMEFORMAT | 無 | '%F %T ' | **啟用時間戳**(顯示格式:YYYY-MM-DD HH:MM:SS) |
PROMPT_COMMAND | 無 | 'history -a; history -c; history -r' | **每條命令後即時追加、清空緩存、重讀文件**,實現多終端實時共享歷史 |
# === History 增強配置 ===
export HISTSIZE=10000
export HISTFILESIZE=50000
export HISTFILE=~/.bash_history_$(hostname -s)
export HISTCONTROL=ignoredups:erasedups
export HISTIGNORE="ls:pwd:exit:clear:history*:bg:fg:cd:cd -"
export HISTTIMEFORMAT='%F %T '
# 多終端實時同步歷史 (關鍵!)
export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"
# 避免歷史記錄敏感信息 (可選)
# export HISTIGNORE="$HISTIGNORE:*password*:*secret*:*token*:*api_key*"
| 語法 | 動作 | 範例 |
|---|---|---|
!! | 重執行上一條命令 | !! → sudo !! (給上一條加 sudo) |
!n | 重執行歷史第 n 條 | !42 |
!-n | 重執行倒數第 n 條 | !-2 (倒數第二條) |
!string | 重執行最近以 string 開頭的命令 | !ssh (最近的 ssh 命令) |
!?string? | 重執行最近包含 string 的命令 | !?config? |
^old^new^ | 快速替換上一條命令中的字符串並執行 | ^vim^cat^ (將上一條 vim 改為 cat) |
!!:s/old/new/ | 同上,更標準語法 | !!:s/test/prod/ |
# 按下 Ctrl+R 進入 (reverse-i-search)`':
# 輸入關鍵字即時匹配歷史
# 反覆按 Ctrl+R 向上翻匹配項
# 按 Enter 執行、Ctrl+E 編輯後執行、Ctrl+G 取消
# 上一條命令: tar -czf backup.tar.gz /etc/nginx /var/www
!!:0 # tar (命令本身)
!!:1 # -czf (第1參數)
!!:$ # /var/www (最後一參數)
!!:* # -czf backup.tar.gz /etc/nginx /var/www (所有參數)
!!:1-2 # -czf backup.tar.gz (範圍)
!!:^ # -czf (第一參數, 同 :1)
!!:* # 所有參數
# 組合使用
cp !!:$ /tmp/ # 複製上一條命令的最後一個參數到 /tmp/
vim !!:2 # 編輯上一條命令的第2個參數
| 參數 | 功能 |
|---|---|
history n | 顯示最近 n 條 |
history -c | 清空當前會話緩存 |
history -d offset | 刪除指定偏移量的條目 (配合 history | grep sensitive) |
history -a | 將當前會話新增命令追加寫入文件 |
history -r | 從文件讀取歷史到當前會話緩存 |
history -w | 將當前會話緩存覆寫文件 |
history -s "cmd" | 手動將命令加入歷史 (不執行) |
history -p "!string" | 展開歷史擴展但不執行 (調試用) |
HISTCONTROL=ignorespace(或 ignoreboth),命令行**以空格開頭**的命令不記入歷史。
export HISTCONTROL=ignoreboth # ignoredups + ignorespace
# 操作:
echo "normal" # 記錄
echo "secret" # 不記錄 (前面有空格)
# 執行含密碼命令後立即
history -d $(history 1 | awk '{print $1}') # 刪除最後一條
set +o history # 當前會話停止記錄
set -o history # 恢復記錄
# 或
unset HISTFILE # 退出時不保存
# 1. 統一收集 (配合 syslog/rsyslog + auditd)
# 2. 關鍵命令標記 (在關鍵操作前後手動標記)
history -s "# === AUDIT: DB Migration Start ==="
# ... 執行遷移 ...
history -s "# === AUDIT: DB Migration End ==="
# 3. 定期導出審計日誌
history -w
cp ~/.bash_history_$(hostname -s) /var/log/audit/bash_history_$(date +%F_%H%M).log
fzf 歷史搜索 (`Ctrl+R`)。history 內建命令搜索,推薦 fzf 整合。
命令歷史不僅是便利工具,更是運維審計、故障複盤、知識沉澱的核心資產。通過調優環境變量、掌握事件設計符與交互搜索、落實敏感信息防洩機制、建立審計同步流程,將 history 打造為**高效、安全、可追溯**的生產力引擎。建議將推薦配置納入基礎鏡像/Ansible 初始化/入職標準環境,全團隊受益。