history 指令:命令歷史的高效利用 文章首圖

history 指令:命令歷史的高效利用

history 指令:命令歷史的高效利用

在 Linux 世界中,history 不僅僅是一個記錄你過去輸入過什麼的簡單工具,它更是提升終端機操作效率的超級加速器。許多初學者往往只記得 history 能列出清單,卻忽略了其背後強大的快捷鍵與變數替換功能。這篇文章將帶領你深入探索 history 的隱藏技巧,讓你在 Ubuntu 22.04 或 Debian 12 環境下,像專家一樣流暢地操作終端機。

基礎回顧與進階查詢

預設情況下,history 會顯示當前 shell 會話中所有的命令紀錄。你可以透過數字來重複執行之前的命令,這比使用鍵盤的 Up 方向鍵來得更快。

$ history
    1  ls -la
    2  cd /var/log
    3  grep error syslog
    4  history

若你的命令歷史非常龐大,直接列出所有內容會造成螢幕混亂。此時,善用 grep 搭配 history 是極佳的篩選策略。由於 history 輸出的是帶有編號的純文字,我們可以直接過濾關鍵字:

$ history | grep ssh
  102  ssh user@remote-server
  105  ssh-keygen -t ed25519
  110  scp file.tar.gz user@remote-server:/tmp

魔法符號 !!!n

這是 history 最實用的核心功能之一。在 Bash 中,你可以使用驚嘆號 (!) 來引用歷史命令。

  1. 重複上一個命令:使用 !!。這在需要反覆執行同一個指令(例如重複安裝套件或重新啟動服務)時非常高效。
  2. 引用特定編號的命令:使用 !數字。例如 !105 會執行歷史清單中編號 105 的命令。

讓我們看一個實際範例,假設你不小心打錯了上一個命令的參數,但又想保留原命令的其他部分:

$ ls /etc/nginx
ls: cannot access '/etc/nginx': No such file or directory
$ !!:p  # 使用 :p 僅列印而不執行,確認內容
ls /etc/nginx

參數替換與字串修飾

history 支援更進階的字串修飾符號,格式為 !n:修飾符。這能讓你在不重新輸入長路徑或長命令的情況下,僅修改其中一小部分。

  • :h (Head):取路徑的目錄部分。
  • :t (Tail):取路徑的檔案名稱部分。
  • :r (Root):去掉副檔名。
  • :e (Extension):僅取副檔名。

實際範例:

假設你剛剛編輯了一個檔案 /home/user/project/config.yaml,現在想將其複製到 /backup 目錄,但想更改副檔名為 .bak

# 假設上一個命令是:vim /home/user/project/config.yaml
$ cp !$:r.bak /backup/
# Bash 會將其展開為:cp /home/user/project/config.bak /backup/

另一個常見場景是重複上一個命令並替換第一個參數。使用 ^old^new 可以快速修正錯誤:

$ apt install vim
# 假設你其實想安裝 nano
$ ^vim^nano
apt install nano

歷史紀錄的儲存與自訂

預設情況下,Bash 將歷史紀錄暫存在記憶體中,當終端機關閉時,會寫入家目錄下的 .bash_history 檔案。你可以透過環境變數 HISTSIZEHISTFILESIZE 來控制紀錄的數量。

在 Ubuntu 22.04 中,建議將這些設定加入 ~/.bashrc

# 設定記憶體中保留的命令數量
export HISTSIZE=10000
# 設定歷史檔案中保留的命令數量
export HISTFILESIZE=20000
# 忽略以空格開頭的命令(避免記錄敏感密碼)
export HISTCONTROL=ignorespace
# 避免重複記錄相同的命令
export HISTCONTROL=ignoredups

設定完成後,記得執行 source ~/.bashrc 讓設定生效。

常見問題解答

Q1: 為什麼我的 history 清單是空的,或者沒有記錄到我剛才輸入的命令?

這通常是因為 HISTSIZE 被設為 0,或者你正在使用非互動式 shell(如腳本執行環境)。此外,如果你使用 sudo 執行命令,預設情況下 sudo 不會繼承當前使用者的 history 變數。若要記錄 sudo 命令,請確保 /etc/sudoers 中未禁用 env_keep 中的相關歷史變數,或使用 sudo -i 進入 root 環境後再操作。

Q2: 如何永久刪除歷史紀錄中的特定敏感資訊(如密碼)?

不要手動編輯 .bash_history 檔案,因為這可能導致檔案格式錯亂。正確的做法是利用 history -d 指令刪除特定編號的命令,然後執行 history -w 重新寫入檔案。

$ history | grep password
  501  mysql -u root -ppassword123
$ history -d 501
$ history -w

小結

掌握 history 的高階用法,能顯著減少你的打字時間並降低輸入錯誤的機率。從簡單的 !! 重複執行,到複雜的字串修飾符號,這些技巧能讓你在 Linux 終端機中遊刃有餘。建議你在日常工作中刻意練習使用 !n 和參數修飾符,很快地,這些快捷操作將成為你的肌肉記憶,大幅提升你的工作效率。