シェルの履歴展開入門:!! や !$ で直前のコマンドを使い回す
bash・zsh には「履歴展開(ヒストリ展開)」という機能があります。直前のコマンドや引数を呼び出せるため、同じ文字列を打ち直す手間が省けます。
!! はビックリマーク2つ、!$ はビックリマーク+ドル記号です。「ビックリマークビックリマーク 使い方」「ビックリマーク シェル」「エクスクラメーション2つ シェル」で検索してたどり着いた方も同じものです。
よくある使い方
ls /var/log/nginx cat !!:$ # → cat /var/log/nginx
!!:$ は「直前のコマンドの最後の引数」を意味します。ls でパスを確認して cat で中身を見る、といった操作がそのまま書けます。
!! :直前のコマンドをそのまま実行する
cat /etc/hosts !! # → cat /etc/hosts(同じコマンドを再実行)
権限エラーになったときに sudo を付けて再実行するのが定番の使い方です。
cat /etc/sudoers # Permission denied sudo !! # → sudo cat /etc/sudoers
!$ :直前のコマンドの最後の引数
!$ は !!:$ の短縮形です。どちらも同じ意味です。
mkdir -p /tmp/work/logs cd !$ # → cd /tmp/work/logs
ls hoge.txt cat !$ # → cat hoge.txt
!^ :直前のコマンドの最初の引数
diff old.txt new.txt cp !^ backup.txt # → cp old.txt backup.txt
!!:n :n番目の引数
コマンド名を !!:0、1番目の引数を !!:1、2番目を !!:2 と指定します。
cp /src/file.txt /dst/file.txt ls -l !!:2 # → ls -l /dst/file.txt
git commit -m "fix: バグ修正" echo !!:0 # → git echo !!:1 # → commit echo !!:3 # → "fix: バグ修正"
!!:* :直前のコマンドの全引数
コマンド名を除いた引数すべてを取り出します。
rsync -av /src/ /dst/ ls !!:* # → ls -av /src/ /dst/
!!:n-m :引数の範囲を指定する
echo a b c d e echo !!:2-4 # → echo b c d
!string :string で始まる直近のコマンドを再実行する
!git # git で始まる最後のコマンドを実行
!ssh # ssh で始まる最後のコマンドを実行
実行前に確認したい場合は :p を付けると表示だけして実行しません。
!git:p # git commit -m "fix: バグ修正" ← 実行せず表示だけ
oldnew :直前のコマンドの文字列を置換して再実行する
タイポを直したいときに使います。
git chekcout main # error: pathspec 'chekcout' did not match any file(s) ^chekcout^checkout # → git checkout main
curl http://staging.example.com/api/users ^staging^prod # → curl http://prod.example.com/api/users
まとめ
| 書き方 | 展開される内容 |
|---|---|
!! |
直前のコマンド全体 |
!$ |
直前のコマンドの最後の引数 |
!^ |
直前のコマンドの最初の引数 |
!!:n |
直前のコマンドのn番目のトークン(0=コマンド名) |
!!:* |
直前のコマンドの全引数(コマンド名除く) |
!!:n-m |
直前のコマンドのn〜m番目のトークン |
!string |
stringで始まる直近のコマンド |
!string:p |
実行せず表示だけ |
^old^new |
直前のコマンドのoldをnewに置換して実行 |
使いどころ
# ls で確認したパスをそのまま cat に渡す ls /var/log/app.log cat !$ # Permission denied → sudo で再実行 cat /etc/sudoers sudo !! # タイポを修正して再実行 git psuh origin main ^psuh^push
コマンドの出力を加工するには「macでjqを使う:JSONをコマンドラインで操作する方法」も参照してください。
historyをインクリメンタルに絞り込むには「fzf入門:zshのhistory検索・ファイル検索を強化する設定」も参照してください。