熟練掌握 Shell 內建展開與歷史擴展機制,能讓日常操作、腳本編寫事半功倍。本文精選高頻實用技巧,附帶原理解析。
$ mv thisisareallylongfilename{,.txt}
# 展開為: mv thisisareallylongfilename thisisareallylongfilename.txt
原理:{A,B} 展開為 A B;{,.txt} 即 {空字符串,.txt} → 空字符串與 .txt。
腳本價值:Tab 補全只能交互式用,腳本中大括號展開是唯一靠譜的「少打字」手段。
$ mv foo.{jpeg,jpg}
# 展開為: mv foo.jpeg foo.jpg
$ mkdir -p /var/www/{html,logs,backup}/{site1,site2,site3}
# 一次創建 9 個目錄
$ touch report_{jan,feb,mar,apr,may,jun}.md
# 創建 6 個文件
$ echo {1..10} # 1 2 3 ... 10
$ echo {01..10} # 01 02 ... 10 (保留寬度)
$ echo {a..z} # a b c ... z
$ echo {1..10..2} # 1 3 5 7 9 (步長 2,Bash 4.0+)
| 語法 | 含義 | 示例 |
|---|---|---|
!! | 上一條完整命令 | sh !! 以 sh 重新執行上一條被拒絕的腳本 |
!n | 歷史第 n 條命令 | !42 執行 history 第 42 條 |
!-n | 倒數第 n 條命令 | !-2 執行倒數第二條 |
!string | 最近一條以 string 開頭的命令 | !ssh 重複最近的 ssh 連接 |
!?string? | 最近一條包含 string 的命令 | !?config? 找最近操作 config 的命令 |
^old^new^ | 替換上一條命令中的 old 為 new 並執行 | ^nginx^apache^ 將上條 nginx 改為 apache |
| 語法 | 含義 | 示例場景 |
|---|---|---|
!* | 上一條命令的所有參數 (不含命令本身) | ls /tmp/somedir 失敗 → mkdir -p !* 即 mkdir -p /tmp/somedir |
!$ | 上一條命令的最後一個參數 | vim /etc/nginx/nginx.conf → cat !$ 查看該文件 |
!^ | 上一條命令的第一個參數 | scp file.txt server:/path → rm !^ 刪除本地文件 |
!:n | 上一條命令的第 n 個參數 (n≥1) | cp a.txt b.txt c.txt → mv !:2 /backup 移動 b.txt |
!:n-m | 第 n 到第 m 個參數 | tar -czf backup.tar.gz /etc /home /var → ls -l !:2-3 列出 /home /var |
!:* | 同 !* | |
!:- | 除最後一個外的所有參數 |
# 1. 快速備份並編輯配置
cp /etc/nginx/nginx.conf{,.bak} && vim /etc/nginx/nginx.conf
# 2. 批量重命名: .htm → .html
for f in *.htm; do mv "$f" "${f%.htm}.html"; done
# 或 (zsh/Bash 4+)
for f in *.htm; mv $f $f:r.html
# 3. 利用歷史參數快速切換目錄
cd /very/long/path/to/project/src/main/java/com/example
# ...做些事...
cd !$:h # 切換到上一條命令最後參數的父目錄 (/very/long/path/to/project/src/main/java/com/example)
# 4. 組合 sudo 重跑
!! 發現權限不足
sudo !! # 自動在上一條命令前加 sudo 執行
# ~/.bashrc / ~/.zshrc
HISTSIZE=10000 # 內存保留 1萬條
HISTFILESIZE=20000 # 文件保留 2萬條
HISTCONTROL=ignoreboth:erasedups # 忽略空格開頭/重複命令
HISTTIMEFORMAT='%F %T ' # 顯示時間戳
shopt -s histappend # 追加不覆蓋 (多終端共享)
shopt -s cmdhist # 多行命令合並存儲
PROMPT_COMMAND='history -a' # 即時寫入文件
大括號展開解決「批量生成」,歷史擴展解決「參數復用」,兩者結合讓命令行從「輸入工具」進化為「思維延伸」。養成 history | grep 找模式、!: 精準取參的習慣,你的終端效率將質變。